! function() {
	var requirejs, require, define;
	! function(global) {
		"use strict";

		function isFunction(a) {
			return "[object Function]" === ostring.call(a)
		}

		function isArray(a) {
			return "[object Array]" === ostring.call(a)
		}

		function each(a, b) {
			if (a) {
				var c;
				for (c = 0; c < a.length && (!a[c] || !b(a[c], c, a)); c += 1);
			}
		}

		function eachReverse(a, b) {
			if (a) {
				var c;
				for (c = a.length - 1; c > -1 && (!a[c] || !b(a[c], c, a)); c -= 1);
			}
		}

		function hasProp(a, b) {
			return a.hasOwnProperty(b)
		}

		function eachProp(a, b) {
			var c;
			for (c in a)
				if (a.hasOwnProperty(c) && b(a[c], c)) break
		}

		function mixin(a, b, c, d) {
			return b && eachProp(b, function(b, e) {
				!c && hasProp(a, e) || (d && "string" != typeof b ? (a[e] || (a[e] = {}), mixin(a[e], b, c, d)) : a[e] = b)
			}), a
		}

		function bind(a, b) {
			return function() {
				return b.apply(a, arguments)
			}
		}

		function scripts() {
			return document.getElementsByTagName("script")
		}

		function getGlobal(a) {
			if (!a) return a;
			var b = global;
			return each(a.split("."), function(a) {
				b = b[a]
			}), b
		}

		function makeContextModuleFunc(a, b, c) {
			return function() {
				var d, e = aps.call(arguments, 0);
				return c && isFunction(d = e[e.length - 1]) && (d.__requireJsBuild = !0), e.push(b), a.apply(null, e)
			}
		}

		function addRequireMethods(a, b, c) {
			each([
				["toUrl"],
				["undef"],
				["defined", "requireDefined"],
				["specified", "requireSpecified"]
			], function(d) {
				var e = d[1] || d[0];
				a[d[0]] = b ? makeContextModuleFunc(b[e], c) : function() {
					var a = contexts[defContextName];
					return a[e].apply(a, arguments)
				}
			})
		}

		function makeError(a, b, c, d) {
			var e = new Error(b + "\nhttp://requirejs.org/docs/errors.html#" + a);
			return e.requireType = a, e.requireModules = d, c && (e.originalError = c), e
		}

		function newContext(a) {
			function b(a) {
				var b, c;
				for (b = 0; a[b]; b += 1)
					if (c = a[b], "." === c) a.splice(b, 1), b -= 1;
					else if (".." === c) {
					if (1 === b && (".." === a[2] || ".." === a[0])) break;
					b > 0 && (a.splice(b - 1, 2), b -= 2)
				}
			}

			function c(a, c, d) {
				var e, f, g, h, i, j, k, l, m = c && c.split("/"),
					n = m,
					o = y.map,
					p = o && o["*"];
				if (a && "." === a.charAt(0) && (c ? (n = y.pkgs[c] ? m = [c] : m.slice(0, m.length - 1), a = n.concat(a.split("/")), b(a), f = y.pkgs[e = a[0]], a = a.join("/"), f && a === e + "/" + f.main && (a = e)) : 0 === a.indexOf("./") && (a = a.substring(2))), d && (m || p) && o)
					for (h = a.split("/"), i = h.length; i > 0; i -= 1) {
						if (k = h.slice(0, i).join("/"), m)
							for (j = m.length; j > 0; j -= 1)
								if (g = o[m.slice(0, j).join("/")], g && (g = g[k])) {
									l = g;
									break
								}
						if (!l && p && p[k] && (l = p[k]), l) {
							h.splice(0, i, l), a = h.join("/");
							break
						}
					}
				return a
			}

			function d(a) {
				isBrowser && each(scripts(), function(b) {
					return b.getAttribute("data-requiremodule") === a && b.getAttribute("data-requirecontext") === v.contextName ? (b.parentNode.removeChild(b), !0) : void 0
				})
			}

			function e(a) {
				var b = y.paths[a];
				return b && isArray(b) && b.length > 1 ? (d(a), b.shift(), v.undef(a), v.require([a]), !0) : void 0
			}

			function f(a, b, d, e) {
				var f, g, h, i = a ? a.indexOf("!") : -1,
					j = null,
					k = b ? b.name : null,
					l = a,
					m = !0,
					n = "";
				return a || (m = !1, a = "_@r" + (E += 1)), -1 !== i && (j = a.substring(0, i), a = a.substring(i + 1, a.length)), j && (j = c(j, k, e), g = C[j]), a && (j ? n = g && g.normalize ? g.normalize(a, function(a) {
					return c(a, k, e)
				}) : c(a, k, e) : (n = c(a, k, e), f = v.nameToUrl(n))), h = !j || g || d ? "" : "_unnormalized" + (F += 1), {
					prefix: j,
					name: n,
					parentMap: b,
					unnormalized: !!h,
					url: f,
					originalName: l,
					isDefine: m,
					id: (j ? j + "!" + n : n) + h
				}
			}

			function g(a) {
				var b = a.id,
					c = z[b];
				return c || (c = z[b] = new v.Module(a)), c
			}

			function h(a, b, c) {
				var d = a.id,
					e = z[d];
				!hasProp(C, d) || e && !e.defineEmitComplete ? g(a).on(b, c) : "defined" === b && c(C[d])
			}

			function i(a, b) {
				var c = a.requireModules,
					d = !1;
				b ? b(a) : (each(c, function(b) {
					var c = z[b];
					c && (c.error = a, c.events.error && (d = !0, c.emit("error", a)))
				}), d || req.onError(a))
			}

			function j() {
				globalDefQueue.length && (apsp.apply(B, [B.length - 1, 0].concat(globalDefQueue)), globalDefQueue = [])
			}

			function k(a, b, c) {
				var d = a && a.map,
					e = makeContextModuleFunc(c || v.require, d, b);
				return addRequireMethods(e, v, d), e.isBrowser = isBrowser, e
			}

			function l(a) {
				delete z[a], each(G, function(b, c) {
					return b.map.id === a ? (G.splice(c, 1), b.defined || (v.waitCount -= 1), !0) : void 0
				})
			}

			function m(a, b) {
				var c, d = a.map.id,
					e = a.depMaps;
				if (a.inited) return b[d] ? a : (b[d] = !0, each(e, function(a) {
					var e = a.id,
						f = z[e];
					if (f) return f.inited && f.enabled ? c = m(f, mixin({}, b)) : (c = null, delete b[d], !0)
				}), c)
			}

			function n(a, b, c) {
				var d = a.map.id,
					e = a.depMaps;
				if (a.inited && a.map.isDefine) return b[d] ? C[d] : (b[d] = a, each(e, function(e) {
					var f, g = e.id,
						h = z[g];
					if (!w[g] && h) {
						if (!h.inited || !h.enabled) return void(c[d] = !0);
						f = n(h, b, c), c[g] || a.defineDepById(g, f)
					}
				}), a.check(!0), C[d])
			}

			function o(a) {
				a.check()
			}

			function p() {
				var a, b, c, f, g = 1e3 * y.waitSeconds,
					h = g && v.startTime + g < (new Date).getTime(),
					j = [],
					k = !1,
					l = !0;
				if (!t) return t = !0, eachProp(z, function(c) {
					if (a = c.map, b = a.id, c.enabled && !c.error)
						if (!c.inited && h) e(b) ? (f = !0, k = !0) : (j.push(b), d(b));
						else if (!c.inited && c.fetched && a.isDefine && (k = !0, !a.prefix)) return l = !1
				}), h && j.length ? (c = makeError("timeout", "Load timeout for modules: " + j, null, j), c.contextName = v.contextName, i(c)) : (l && (each(G, function(a) {
					if (!a.defined) {
						var b = m(a, {}),
							c = {};
						b && (n(b, c, {}), eachProp(c, o))
					}
				}), eachProp(z, o)), (!h || f) && k && (isBrowser || isWebWorker) && !x && (x = setTimeout(function() {
					x = 0, p()
				}, 50)), t = !1, void 0)
			}

			function q(a) {
				g(f(a[0], null, !0)).init(a[1], a[2])
			}

			function r(a, b, c, d) {
				a.detachEvent && !isOpera ? d && a.detachEvent(d, b) : a.removeEventListener(c, b, !1)
			}

			function s(a) {
				var b = a.currentTarget || a.srcElement;
				return r(b, v.onScriptLoad, "load", "onreadystatechange"), r(b, v.onScriptError, "error"), {
					node: b,
					id: b && b.getAttribute("data-requiremodule")
				}
			}
			var t, u, v, w, x, y = {
					waitSeconds: 7,
					baseUrl: "./",
					paths: {},
					pkgs: {},
					shim: {}
				},
				z = {},
				A = {},
				B = [],
				C = {},
				D = {},
				E = 1,
				F = 1,
				G = [];
			return w = {
				require: function(a) {
					return k(a)
				},
				exports: function(a) {
					return a.usingExports = !0, a.map.isDefine ? a.exports = C[a.map.id] = {} : void 0
				},
				module: function(a) {
					return a.module = {
						id: a.map.id,
						uri: a.map.url,
						config: function() {
							return y.config && y.config[a.map.id] || {}
						},
						exports: C[a.map.id]
					}
				}
			}, u = function(a) {
				this.events = A[a.id] || {}, this.map = a, this.shim = y.shim[a.id], this.depExports = [], this.depMaps = [], this.depMatched = [], this.pluginMaps = {}, this.depCount = 0
			}, u.prototype = {
				init: function(a, b, c, d) {
					d = d || {}, this.inited || (this.factory = b, c ? this.on("error", c) : this.events.error && (c = bind(this, function(a) {
						this.emit("error", a)
					})), this.depMaps = a && a.slice(0), this.depMaps.rjsSkipMap = a.rjsSkipMap, this.errback = c, this.inited = !0, this.ignore = d.ignore, d.enabled || this.enabled ? this.enable() : this.check())
				},
				defineDepById: function(a, b) {
					var c;
					return each(this.depMaps, function(b, d) {
						return b.id === a ? (c = d, !0) : void 0
					}), this.defineDep(c, b)
				},
				defineDep: function(a, b) {
					this.depMatched[a] || (this.depMatched[a] = !0, this.depCount -= 1, this.depExports[a] = b)
				},
				fetch: function() {
					if (!this.fetched) {
						this.fetched = !0, v.startTime = (new Date).getTime();
						var a = this.map;
						return this.shim ? void k(this, !0)(this.shim.deps || [], bind(this, function() {
							return a.prefix ? this.callPlugin() : this.load()
						})) : a.prefix ? this.callPlugin() : this.load()
					}
				},
				load: function() {
					var a = this.map.url;
					D[a] || (D[a] = !0, v.load(this.map.id, a))
				},
				check: function(a) {
					if (this.enabled && !this.enabling) {
						var b, c, d = this.map.id,
							e = this.depExports,
							f = this.exports,
							g = this.factory;
						if (this.inited) {
							if (this.error) this.emit("error", this.error);
							else if (!this.defining) {
								if (this.defining = !0, this.depCount < 1 && !this.defined) {
									if (isFunction(g)) {
										if (this.events.error) try {
											f = v.execCb(d, g, e, f)
										} catch (h) {
											b = h
										} else f = v.execCb(d, g, e, f);
										if (this.map.isDefine && (c = this.module, c && void 0 !== c.exports && c.exports !== this.exports ? f = c.exports : void 0 === f && this.usingExports && (f = this.exports)), b) return b.requireMap = this.map, b.requireModules = [this.map.id], b.requireType = "define", i(this.error = b)
									} else f = g;
									this.exports = f, this.map.isDefine && !this.ignore && (C[d] = f, req.onResourceLoad && req.onResourceLoad(v, this.map, this.depMaps)), delete z[d], this.defined = !0, v.waitCount -= 1, 0 === v.waitCount && (G = [])
								}
								this.defining = !1, a || this.defined && !this.defineEmitted && (this.defineEmitted = !0, this.emit("defined", this.exports), this.defineEmitComplete = !0)
							}
						} else this.fetch()
					}
				},
				callPlugin: function() {
					var a = this.map,
						b = a.id,
						d = f(a.prefix, null, !1, !0);
					h(d, "defined", bind(this, function(d) {
						var e, j, m, n = this.map.name,
							o = this.map.parentMap ? this.map.parentMap.name : null;
						return this.map.unnormalized ? (d.normalize && (n = d.normalize(n, function(a) {
							return c(a, o, !0)
						}) || ""), j = f(a.prefix + "!" + n, this.map.parentMap, !1, !0), h(j, "defined", bind(this, function(a) {
							this.init([], function() {
								return a
							}, null, {
								enabled: !0,
								ignore: !0
							})
						})), m = z[j.id], m && (this.events.error && m.on("error", bind(this, function(a) {
							this.emit("error", a)
						})), m.enable()), void 0) : (e = bind(this, function(a) {
							this.init([], function() {
								return a
							}, null, {
								enabled: !0
							})
						}), e.error = bind(this, function(a) {
							this.inited = !0, this.error = a, a.requireModules = [b], eachProp(z, function(a) {
								0 === a.map.id.indexOf(b + "_unnormalized") && l(a.map.id)
							}), i(a)
						}), e.fromText = function(a, b) {
							var c = useInteractive;
							c && (useInteractive = !1), g(f(a)), req.exec(b), c && (useInteractive = !0), v.completeLoad(a)
						}, d.load(a.name, k(a.parentMap, !0, function(a, b) {
							return a.rjsSkipMap = !0, v.require(a, b)
						}), e, y), void 0)
					})), v.enable(d, this), this.pluginMaps[d.id] = d
				},
				enable: function() {
					this.enabled = !0, this.waitPushed || (G.push(this), v.waitCount += 1, this.waitPushed = !0), this.enabling = !0, each(this.depMaps, bind(this, function(a, b) {
						var c, d, e;
						if ("string" == typeof a) {
							if (a = f(a, this.map.isDefine ? this.map : this.map.parentMap, !1, !this.depMaps.rjsSkipMap), this.depMaps[b] = a, e = w[a.id], e) return void(this.depExports[b] = e(this));
							this.depCount += 1, h(a, "defined", bind(this, function(a) {
								this.defineDep(b, a), this.check()
							})), this.errback && h(a, "error", this.errback)
						}
						c = a.id, d = z[c], !w[c] && d && !d.enabled && v.enable(a, this)
					})), eachProp(this.pluginMaps, bind(this, function(a) {
						var b = z[a.id];
						b && !b.enabled && v.enable(a, this)
					})), this.enabling = !1, this.check()
				},
				on: function(a, b) {
					var c = this.events[a];
					c || (c = this.events[a] = []), c.push(b)
				},
				emit: function(a, b) {
					each(this.events[a], function(a) {
						a(b)
					}), "error" === a && delete this.events[a]
				}
			}, v = {
				config: y,
				contextName: a,
				registry: z,
				defined: C,
				urlFetched: D,
				waitCount: 0,
				defQueue: B,
				Module: u,
				makeModuleMap: f,
				configure: function(a) {
					a.baseUrl && "/" !== a.baseUrl.charAt(a.baseUrl.length - 1) && (a.baseUrl += "/");
					var b = y.pkgs,
						c = y.shim,
						d = y.paths,
						e = y.map;
					mixin(y, a, !0), y.paths = mixin(d, a.paths, !0), a.map && (y.map = mixin(e || {}, a.map, !0, !0)), a.shim && (eachProp(a.shim, function(a, b) {
						isArray(a) && (a = {
							deps: a
						}), a.exports && !a.exports.__buildReady && (a.exports = v.makeShimExports(a.exports)), c[b] = a
					}), y.shim = c), a.packages && (each(a.packages, function(a) {
						var c;
						a = "string" == typeof a ? {
							name: a
						} : a, c = a.location, b[a.name] = {
							name: a.name,
							location: c || a.name,
							main: (a.main || "main").replace(currDirRegExp, "").replace(jsSuffixRegExp, "")
						}
					}), y.pkgs = b), eachProp(z, function(a, b) {
						a.map = f(b)
					}), (a.deps || a.callback) && v.require(a.deps || [], a.callback)
				},
				makeShimExports: function(a) {
					var b;
					return "string" == typeof a ? (b = function() {
						return getGlobal(a)
					}, b.exports = a, b) : function() {
						return a.apply(global, arguments)
					}
				},
				requireDefined: function(a, b) {
					return hasProp(C, f(a, b, !1, !0).id)
				},
				requireSpecified: function(a, b) {
					return a = f(a, b, !1, !0).id, hasProp(C, a) || hasProp(z, a)
				},
				require: function(b, c, d, e) {
					var h, k, l, m, n;
					if ("string" == typeof b) return isFunction(c) ? i(makeError("requireargs", "Invalid require call"), d) : req.get ? req.get(v, b, c) : (h = b, e = c, l = f(h, e, !1, !0), k = l.id, hasProp(C, k) ? C[k] : i(makeError("notloaded", 'Module name "' + k + '" has not been loaded yet for context: ' + a)));
					for (d && !isFunction(d) && (e = d, d = void 0), c && !isFunction(c) && (e = c, c = void 0), j(); B.length;) {
						if (n = B.shift(), null === n[0]) return i(makeError("mismatch", "Mismatched anonymous define() module: " + n[n.length - 1]));
						q(n)
					}
					return m = g(f(null, e)), m.init(b, c, d, {
						enabled: !0
					}), p(), v.require
				},
				undef: function(a) {
					var b = f(a, null, !0),
						c = z[a];
					delete C[a], delete D[b.url], delete A[a], c && (c.events.defined && (A[a] = c.events), l(a))
				},
				enable: function(a, b) {
					var c = z[a.id];
					c && g(a).enable()
				},
				completeLoad: function(a) {
					var b, c, d, f = y.shim[a] || {},
						g = f.exports && f.exports.exports;
					for (j(); B.length;) {
						if (c = B.shift(), null === c[0]) {
							if (c[0] = a, b) break;
							b = !0
						} else c[0] === a && (b = !0);
						q(c)
					}
					if (d = z[a], !b && !C[a] && d && !d.inited) {
						if (y.enforceDefine && (!g || !getGlobal(g))) {
							if (e(a)) return;
							return i(makeError("nodefine", "No define call for " + a, null, [a]))
						}
						q([a, f.deps || [], f.exports])
					}
					p()
				},
				toUrl: function(a, b) {
					var d = a.lastIndexOf("."),
						e = null;
					return -1 !== d && (e = a.substring(d, a.length), a = a.substring(0, d)), v.nameToUrl(c(a, b && b.id, !0), e)
				},
				nameToUrl: function(a, b) {
					var c, d, e, f, g, h, i, j, k;
					if (req.jsExtRegExp.test(a)) j = a + (b || "");
					else {
						for (c = y.paths, d = y.pkgs, g = a.split("/"), h = g.length; h > 0; h -= 1) {
							if (i = g.slice(0, h).join("/"), e = d[i], k = c[i], k) {
								isArray(k) && (k = k[0]), g.splice(0, h, k);
								break
							}
							if (e) {
								f = a === e.name ? e.location + "/" + e.main : e.location, g.splice(0, h, f);
								break
							}
						}
						j = g.join("/") + (b || ".js"), j = ("/" === j.charAt(0) || j.match(/^[\w\+\.\-]+:/) ? "" : y.baseUrl) + j
					}
					return y.urlArgs ? j + ((-1 === j.indexOf("?") ? "?" : "&") + y.urlArgs) : j
				},
				load: function(a, b) {
					req.load(v, a, b)
				},
				execCb: function(a, b, c, d) {
					return b.apply(d, c)
				},
				onScriptLoad: function(a) {
					if ("load" === a.type || readyRegExp.test((a.currentTarget || a.srcElement).readyState)) {
						interactiveScript = null;
						var b = s(a);
						v.completeLoad(b.id)
					}
				},
				onScriptError: function(a) {
					var b = s(a);
					return e(b.id) ? void 0 : i(makeError("scripterror", "Script error", a, [b.id]))
				}
			}
		}

		function getInteractiveScript() {
			return interactiveScript && "interactive" === interactiveScript.readyState ? interactiveScript : (eachReverse(scripts(), function(a) {
				return "interactive" === a.readyState ? interactiveScript = a : void 0
			}), interactiveScript)
		}
		var version = "2.0.4",
			commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/gm,
			cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
			jsSuffixRegExp = /\.js$/,
			currDirRegExp = /^\.\//,
			ostring = Object.prototype.toString,
			ap = Array.prototype,
			aps = ap.slice,
			apsp = ap.splice,
			isBrowser = "undefined" != typeof window && !!navigator && !!document,
			isWebWorker = !isBrowser && "undefined" != typeof importScripts,
			readyRegExp = isBrowser && "PLAYSTATION 3" === navigator.platform ? /^complete$/ : /^(complete|loaded)$/,
			defContextName = "_",
			isOpera = "undefined" != typeof opera && "[object Opera]" === opera.toString(),
			contexts = {},
			cfg = {},
			globalDefQueue = [],
			useInteractive = !1,
			req, s, head, baseElement, dataMain, src, interactiveScript, currentlyAddingScript, mainScript, subPath;
		if ("undefined" == typeof define) {
			if ("undefined" != typeof requirejs) {
				if (isFunction(requirejs)) return;
				cfg = requirejs, requirejs = void 0
			}
			"undefined" != typeof require && !isFunction(require) && (cfg = require, require = void 0), req = requirejs = function(a, b, c, d) {
				var e, f, g = defContextName;
				return !isArray(a) && "string" != typeof a && (f = a, isArray(b) ? (a = b, b = c, c = d) : a = []), f && f.context && (g = f.context), e = contexts[g], e || (e = contexts[g] = req.s.newContext(g)), f && e.configure(f), e.require(a, b, c)
			}, req.config = function(a) {
				return req(a)
			}, require || (require = req), req.version = version, req.jsExtRegExp = /^\/|:|\?|\.js$/, req.isBrowser = isBrowser, s = req.s = {
				contexts: contexts,
				newContext: newContext
			}, req({}), addRequireMethods(req), isBrowser && (head = s.head = document.getElementsByTagName("head")[0], baseElement = document.getElementsByTagName("base")[0], baseElement && (head = s.head = baseElement.parentNode)), req.onError = function(a) {
				throw a
			}, req.load = function(a, b, c) {
				var d, e = a && a.config || {};
				return isBrowser ? (d = e.xhtml ? document.createElementNS("http://www.w3.org/1999/xhtml", "html:script") : document.createElement("script"), d.type = e.scriptType || "text/javascript", d.charset = "utf-8", d.async = !0, d.setAttribute("data-requirecontext", a.contextName), d.setAttribute("data-requiremodule", b), !d.attachEvent || d.attachEvent.toString && d.attachEvent.toString().indexOf("[native code") < 0 || isOpera ? (d.addEventListener("load", a.onScriptLoad, !1), d.addEventListener("error", a.onScriptError, !1)) : (useInteractive = !0, d.attachEvent("onreadystatechange", a.onScriptLoad)), d.src = c, currentlyAddingScript = d, baseElement ? head.insertBefore(d, baseElement) : head.appendChild(d), currentlyAddingScript = null, d) : void(isWebWorker && (importScripts(c), a.completeLoad(b)))
			}, isBrowser && eachReverse(scripts(), function(a) {
				return head || (head = a.parentNode), dataMain = a.getAttribute("data-main"), dataMain ? (cfg.baseUrl || (src = dataMain.split("/"), mainScript = src.pop(), subPath = src.length ? src.join("/") + "/" : "./", cfg.baseUrl = subPath, dataMain = mainScript), dataMain = dataMain.replace(jsSuffixRegExp, ""), cfg.deps = cfg.deps ? cfg.deps.concat(dataMain) : [dataMain], !0) : void 0
			}), define = function(a, b, c) {
				var d, e;
				"string" != typeof a && (c = b, b = a, a = null), isArray(b) || (c = b, b = []), !b.length && isFunction(c) && c.length && (c.toString().replace(commentRegExp, "").replace(cjsRequireRegExp, function(a, c) {
					b.push(c)
				}), b = (1 === c.length ? ["require"] : ["require", "exports", "module"]).concat(b)), useInteractive && (d = currentlyAddingScript || getInteractiveScript(), d && (a || (a = d.getAttribute("data-requiremodule")), e = contexts[d.getAttribute("data-requirecontext")])), (e ? e.defQueue : globalDefQueue).push([a, b, c])
			}, define.amd = {
				jQuery: !0
			}, req.exec = function(text) {
				return eval(text)
			}, req(cfg)
		}
	}(this), define("../lib/require", function() {}),
		function(a) {
			function b(a) {
				var b = document.createEvent("CustomEvent");
				b.initCustomEvent("fullscreenchange", !0, !1, null), document.dispatchEvent(b)
			}

			function c(a) {
				var b = document.createEvent("CustomEvent");
				b.initCustomEvent("fullscreenerror", !0, !1, null), document.dispatchEvent(b)
			}

			function d(a) {
				var b = document.createEvent("CustomEvent");
				b.initCustomEvent("pointerlockchange", !0, !1, null), document.dispatchEvent(b)
			}

			function e(a) {
				var b = document.createEvent("CustomEvent");
				b.initCustomEvent("pointerlockerror", !0, !1, null), document.dispatchEvent(b)
			}
			var f, g = (a.HTMLElement || a.Element).prototype,
				h = a.GameShim = {
					supports: {
						fullscreen: !0,
						pointerLock: !0,
						gamepad: !0,
						highResTimer: !0
					}
				};
			! function() {
				var a, b = 0,
					c = ["webkit", "moz", "ms", "o"];
				for (a = 0; a < c.length && !window.requestAnimationFrame; ++a) window.requestAnimationFrame = window[c[a] + "RequestAnimationFrame"];
				for (window.cancelAnimationFrame = window.cancelAnimationFrame || window.cancelRequestAnimationFrame, a = 0; a < c.length && !window.cancelAnimationFrame; ++a) window.cancelAnimationFrame = window[c[a] + "CancelAnimationFrame"] || window[c[a] + "CancelRequestAnimationFrame"];
				window.requestAnimationFrame || (window.requestAnimationFrame = function(a, c) {
					var d = Date.now(),
						e = Math.max(0, 16 - (d - b)),
						f = window.setTimeout(function() {
							a(d + e)
						}, e);
					return b = d + e, f
				}), window.cancelAnimationFrame || (window.cancelAnimationFrame = function(a) {
					clearTimeout(a)
				}), window.animationStartTime || (f = function() {
					for (a = 0; a < c.length; ++a)
						if (window[c[a] + "AnimationStartTime"]) return function() {
							return window[c[a] + "AnimationStartTime"]
						};
					return function() {
						return Date.now()
					}
				}(), Object.defineProperty(window, "animationStartTime", {
					enumerable: !0,
					configurable: !1,
					writeable: !1,
					get: f
				}))
			}(), document.hasOwnProperty("fullscreenEnabled") || (f = function() {
				return "webkitIsFullScreen" in document ? function() {
					return webkitRequestFullScreen in document
				} : "mozFullScreenEnabled" in document ? function() {
					return document.mozFullScreenEnabled
				} : (h.supports.fullscreen = !1, function() {
					return !1
				})
			}(), Object.defineProperty(document, "fullscreenEnabled", {
				enumerable: !0,
				configurable: !1,
				writeable: !1,
				get: f
			})), document.hasOwnProperty("fullscreenElement") || (f = function() {
				for (var a = 0, b = ["webkitCurrentFullScreenElement", "webkitFullscreenElement", "mozFullScreenElement"]; a < b.length; a++)
					if (b[a] in document) return function() {
						return document[b[a]]
					};
				return function() {
					return null
				}
			}(), Object.defineProperty(document, "fullscreenElement", {
				enumerable: !0,
				configurable: !1,
				writeable: !1,
				get: f
			})), document.addEventListener("webkitfullscreenchange", b, !1), document.addEventListener("mozfullscreenchange", b, !1), document.addEventListener("webkitfullscreenerror", c, !1), document.addEventListener("mozfullscreenerror", c, !1), g.requestFullscreen || (g.requestFullscreen = function() {
				return g.webkitRequestFullScreen ? function() {
					this.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)
				} : g.mozRequestFullScreen ? function() {
					this.mozRequestFullScreen()
				} : function() {}
			}()), document.exitFullscreen || (document.exitFullscreen = function() {
				return document.webkitExitFullscreen || document.mozCancelFullScreen || function() {}
			}());
			var i = a.MouseEvent.prototype;
			"movementX" in i || Object.defineProperty(i, "movementX", {
				enumerable: !0,
				configurable: !1,
				writeable: !1,
				get: function() {
					return this.webkitMovementX || this.mozMovementX || 0
				}
			}), "movementY" in i || Object.defineProperty(i, "movementY", {
				enumerable: !0,
				configurable: !1,
				writeable: !1,
				get: function() {
					return this.webkitMovementY || this.mozMovementY || 0
				}
			}), navigator.pointer || (navigator.pointer = navigator.webkitPointer || navigator.mozPointer), document.addEventListener("webkitpointerlockchange", d, !1), document.addEventListener("webkitpointerlocklost", d, !1), document.addEventListener("mozpointerlockchange", d, !1), document.addEventListener("mozpointerlocklost", d, !1), document.addEventListener("webkitpointerlockerror", e, !1), document.addEventListener("mozpointerlockerror", e, !1), document.hasOwnProperty("pointerLockElement") || (f = function() {
				return "webkitPointerLockElement" in document ? function() {
					return document.webkitPointerLockElement
				} : "mozPointerLockElement" in document ? function() {
					return document.mozPointerLockElement
				} : function() {
					return null
				}
			}(), Object.defineProperty(document, "pointerLockElement", {
				enumerable: !0,
				configurable: !1,
				writeable: !1,
				get: f
			})), g.requestPointerLock || (g.requestPointerLock = function() {
				return g.webkitRequestPointerLock ? function() {
					this.webkitRequestPointerLock()
				} : g.mozRequestPointerLock ? function() {
					this.mozRequestPointerLock()
				} : navigator.pointer ? function() {
					var a = this;
					navigator.pointer.lock(a, d, e)
				} : (h.supports.pointerLock = !1, function() {})
			}()), document.exitPointerLock || (document.exitPointerLock = function() {
				return document.webkitExitPointerLock || document.mozExitPointerLock || function() {
					if (navigator.pointer) {
						navigator.pointer.unlock()
					}
				}
			}()), navigator.gamepads || (f = function() {
				if ("webkitGamepads" in navigator) return function() {
					return navigator.webkitGamepads
				};
				if ("mozGamepads" in navigator) return function() {
					return navigator.mozGamepads
				};
				h.supports.gamepad = !1;
				var a = [];
				return function() {
					return a
				}
			}(), Object.defineProperty(navigator, "gamepads", {
				enumerable: !0,
				configurable: !1,
				writeable: !1,
				get: f
			})), window.performance || (window.performance = {}), window.performance.timing || (window.performance.timing = {
				navigationStart: Date.now()
			}), window.performance.now || (window.performance.now = function() {
				return window.performance.webkitNow ? window.performance.webkitNow : (h.supports.highResTimer = !1, function() {
					return Date.now() - window.performance.timing.navigationStart
				})
			}())
		}("undefined" != typeof exports ? global : window), define("game-shim", function() {}), define("text", ["module"], function(a) {
			"use strict";
			var b, c, d, e, f, g = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP", "Msxml2.XMLHTTP.4.0"],
				h = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,
				i = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im,
				j = "undefined" != typeof location && location.href,
				k = j && location.protocol && location.protocol.replace(/\:/, ""),
				l = j && location.hostname,
				m = j && (location.port || void 0),
				n = {},
				o = a.config && a.config() || {};
			return b = {
				version: "2.0.14",
				strip: function(a) {
					if (a) {
						a = a.replace(h, "");
						var b = a.match(i);
						b && (a = b[1])
					} else a = "";
					return a
				},
				jsEscape: function(a) {
					return a.replace(/(['\\])/g, "\\$1").replace(/[\f]/g, "\\f").replace(/[\b]/g, "\\b").replace(/[\n]/g, "\\n").replace(/[\t]/g, "\\t").replace(/[\r]/g, "\\r").replace(/[\u2028]/g, "\\u2028").replace(/[\u2029]/g, "\\u2029")
				},
				createXhr: o.createXhr || function() {
					var a, b, c;
					if ("undefined" != typeof XMLHttpRequest) return new XMLHttpRequest;
					if ("undefined" != typeof ActiveXObject)
						for (b = 0; 3 > b; b += 1) {
							c = g[b];
							try {
								a = new ActiveXObject(c)
							} catch (d) {}
							if (a) {
								g = [c];
								break
							}
						}
					return a
				},
				parseName: function(a) {
					var b, c, d, e = !1,
						f = a.lastIndexOf("."),
						g = 0 === a.indexOf("./") || 0 === a.indexOf("../");
					return -1 !== f && (!g || f > 1) ? (b = a.substring(0, f), c = a.substring(f + 1)) : b = a, d = c || b, f = d.indexOf("!"), -1 !== f && (e = "strip" === d.substring(f + 1), d = d.substring(0, f), c ? c = d : b = d), {
						moduleName: b,
						ext: c,
						strip: e
					}
				},
				xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/,
				useXhr: function(a, c, d, e) {
					var f, g, h, i = b.xdRegExp.exec(a);
					return i ? (f = i[2], g = i[3], g = g.split(":"), h = g[1], g = g[0], !(f && f !== c || g && g.toLowerCase() !== d.toLowerCase() || (h || g) && h !== e)) : !0
				},
				finishLoad: function(a, c, d, e) {
					d = c ? b.strip(d) : d, o.isBuild && (n[a] = d), e(d)
				},
				load: function(a, c, d, e) {
					if (e && e.isBuild && !e.inlineText) return void d();
					o.isBuild = e && e.isBuild;
					var f = b.parseName(a),
						g = f.moduleName + (f.ext ? "." + f.ext : ""),
						h = c.toUrl(g),
						i = o.useXhr || b.useXhr;
					return 0 === h.indexOf("empty:") ? void d() : void(!j || i(h, k, l, m) ? b.get(h, function(c) {
						b.finishLoad(a, f.strip, c, d)
					}, function(a) {
						d.error && d.error(a)
					}) : c([g], function(a) {
						b.finishLoad(f.moduleName + "." + f.ext, f.strip, a, d)
					}))
				},
				write: function(a, c, d, e) {
					if (n.hasOwnProperty(c)) {
						var f = b.jsEscape(n[c]);
						d.asModule(a + "!" + c, "define(function () { return '" + f + "';});\n")
					}
				},
				writeFile: function(a, c, d, e, f) {
					var g = b.parseName(c),
						h = g.ext ? "." + g.ext : "",
						i = g.moduleName + h,
						j = d.toUrl(g.moduleName + h) + ".js";
					b.load(i, d, function(c) {
						var d = function(a) {
							return e(j, a)
						};
						d.asModule = function(a, b) {
							return e.asModule(a, j, b)
						}, b.write(a, i, d, f)
					}, f)
				}
			}, "node" === o.env || !o.env && "undefined" != typeof process && process.versions && process.versions.node && !process.versions["node-webkit"] && !process.versions["atom-shell"] ? (c = require.nodeRequire("fs"), b.get = function(a, b, d) {
				try {
					var e = c.readFileSync(a, "utf8");
					"\ufeff" === e[0] && (e = e.substring(1)), b(e)
				} catch (f) {
					d && d(f)
				}
			}) : "xhr" === o.env || !o.env && b.createXhr() ? b.get = function(a, c, d, e) {
				var f, g = b.createXhr();
				if (g.open("GET", a, !0), e)
					for (f in e) e.hasOwnProperty(f) && g.setRequestHeader(f.toLowerCase(), e[f]);
				o.onXhr && o.onXhr(g, a), g.onreadystatechange = function(b) {
					var e, f;
					4 === g.readyState && (e = g.status || 0, e > 399 && 600 > e ? (f = new Error(a + " HTTP status: " + e), f.xhr = g, d && d(f)) : c(g.responseText), o.onXhrComplete && o.onXhrComplete(g, a))
				}, g.send(null)
			} : "rhino" === o.env || !o.env && "undefined" != typeof Packages && "undefined" != typeof java ? b.get = function(a, b) {
				var c, d, e = "utf-8",
					f = new java.io.File(a),
					g = java.lang.System.getProperty("line.separator"),
					h = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(f), e)),
					i = "";
				try {
					for (c = new java.lang.StringBuffer, d = h.readLine(), d && d.length() && 65279 === d.charAt(0) && (d = d.substring(1)), null !== d && c.append(d); null !== (d = h.readLine());) c.append(g), c.append(d);
					i = String(c.toString())
				} finally {
					h.close()
				}
				b(i)
			} : ("xpconnect" === o.env || !o.env && "undefined" != typeof Components && Components.classes && Components.interfaces) && (d = Components.classes, e = Components.interfaces, Components.utils["import"]("resource://gre/modules/FileUtils.jsm"), f = "@mozilla.org/windows-registry-key;1" in d, b.get = function(a, b) {
				var c, g, h, i = {};
				f && (a = a.replace(/\//g, "\\")), h = new FileUtils.File(a);
				try {
					c = d["@mozilla.org/network/file-input-stream;1"].createInstance(e.nsIFileInputStream), c.init(h, 1, 0, !1), g = d["@mozilla.org/intl/converter-input-stream;1"].createInstance(e.nsIConverterInputStream), g.init(c, "utf-8", c.available(), e.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER), g.readString(c.available(), i), g.close(), c.close(), b(i.value)
				} catch (j) {
					throw new Error((h && h.path || "") + ": " + j)
				}
			}), b
		}), define("text!shaders/advect.frag", [], function() {
			return "precision highp float;\nuniform sampler2D source;\nuniform sampler2D velocity;\nuniform float dt;\nuniform float scale;\nuniform vec2 px1;\nvarying vec2 uv;\nuniform float tension;\n\nvoid main(){\n    gl_FragColor = texture2D(source, uv-texture2D(velocity, uv).xy*dt*px1)*scale*tension;\n}\n"
		}), define("text!shaders/addForce.frag", [], function() {
			return "precision highp float;\n\nuniform vec2 force;\nuniform vec2 center;\nuniform vec2 scale;\nuniform vec2 px;\nvarying vec2 uv;\n\nvoid main(){\n    float distance_ = 1.0-min(length((uv-center)/scale), 1.0);\n    gl_FragColor = vec4(force*distance_, 0, 1);\n}\n"
		}), define("text!shaders/divergence.frag", [], function() {
			return "precision highp float;\nuniform sampler2D velocity;\nuniform float dt;\nuniform vec2 px;\nvarying vec2 uv;\nuniform float divergenceMagnifier;\n\nvoid main(){\n    float x0 = texture2D(velocity, uv-vec2(px.x, 0)).x;\n    float x1 = texture2D(velocity, uv+vec2(px.x, 0)).x;\n    float y0 = texture2D(velocity, uv-vec2(0, px.y)).y;\n    float y1 = texture2D(velocity, uv+vec2(0, px.y)).y;\n    float divergence = (x1-x0 + y1-y0)*divergenceMagnifier;\n    gl_FragColor = vec4(divergence);\n}\n"
		}), define("text!shaders/jacobi.frag", [], function() {
			return "precision highp float;\nuniform sampler2D pressure;\nuniform sampler2D divergence;\nuniform float alpha;\nuniform float beta;\nuniform vec2 px;\nvarying vec2 uv;\n\nvoid main(){\n    float x0 = texture2D(pressure, uv-vec2(px.x, 0)).r;\n    float x1 = texture2D(pressure, uv+vec2(px.x, 0)).r;\n    float y0 = texture2D(pressure, uv-vec2(0, px.y)).r;\n    float y1 = texture2D(pressure, uv+vec2(0, px.y)).r;\n    float d = texture2D(divergence, uv).r;\n    float relaxed = (x0 + x1 + y0 + y1 + alpha * d) * beta;\n    gl_FragColor = vec4(relaxed);\n}\n"
		}), define("text!shaders/subtractPressureGradient.frag", [], function() {
			return "precision highp float;\nuniform sampler2D pressure;\nuniform sampler2D velocity;\nuniform float alpha;\nuniform float beta;\nuniform float scale;\nuniform vec2 px;\nvarying vec2 uv;\n\nvoid main(){\n    float x0 = texture2D(pressure, uv-vec2(px.x, 0)).r;\n    float x1 = texture2D(pressure, uv+vec2(px.x, 0)).r;\n    float y0 = texture2D(pressure, uv-vec2(0, px.y)).r;\n    float y1 = texture2D(pressure, uv+vec2(0, px.y)).r;\n    vec2 v = texture2D(velocity, uv).xy;\n    gl_FragColor = vec4((v-(vec2(x1, y1)-vec2(x0, y0))*0.5)*scale, 1.0, 1.0);\n}\n"
		}), define("text!shaders/visualize.frag", [], function() {
			return "precision lowp float;\nuniform sampler2D velocity;\nuniform float brightness;\nuniform float cursor_intensity;\n\n\nvarying vec2 uv;\n\nvoid main(){\n  lowp float temp = (texture2D(velocity, uv)*cursor_intensity+brightness).x;\n    gl_FragColor = vec4(\n      temp,\n     temp,\n     temp,\n .5);\n}\n"
		}), define("text!shaders/cursor.vertex", [], function() {
			return "precision highp float;\n\nattribute vec3 position;\nuniform vec2 center;\nuniform vec2 px;\nvarying vec2 uv;\n\n\nvoid main(){\n    uv = clamp(position.xy+center, vec2(-1.0+px*2.0), vec2(1.0-px*2.0));\n    gl_Position = vec4(uv, 0.0, 1.0);\n}\n"
		}), define("text!shaders/boundary.vertex", [], function() {
			return "attribute vec3 position;\nattribute vec3 offset;\nvarying vec2 uv;\n\n//precision highp float;\n\nvoid main(){\n    uv = offset.xy*0.5+0.5;\n    gl_Position = vec4(position, 1.0);\n}\n"
		}), define("text!shaders/kernel.vertex", [], function() {
			return "precision highp float;\nattribute vec3 position;\nuniform vec2 px;\nvarying vec2 uv;\n\n\n\nvoid main(){\n    uv = vec2(0.5)+(position.xy)*0.5;\n    gl_Position = vec4(position, 1.0);\n}\n"
		}), define("engine/fragments", ["text!shaders/advect.frag", "text!shaders/addForce.frag", "text!shaders/divergence.frag", "text!shaders/jacobi.frag", "text!shaders/subtractPressureGradient.frag", "text!shaders/visualize.frag", "text!shaders/cursor.vertex", "text!shaders/boundary.vertex", "text!shaders/kernel.vertex"], function(a, b, c, d, e, f, g, h, i) {
			return {
				resources: {
					"shaders/addForce.frag": b,
					"shaders/advect.frag": a,
					"shaders/boundary.vertex": h,
					"shaders/cursor.vertex": g,
					"shaders/divergence.frag": c,
					"shaders/jacobi.frag": d,
					"shaders/kernel.vertex": i,
					"shaders/subtractPressureGradient.frag": e,
					"shaders/visualize.frag": f
				}
			}
		}), define("engine/clock", ["require", "exports", "module"], function(a, b, c) {
			var d = b,
				e = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame;
			d.Clock = function() {
				this.running = !1, this.interval = null, this.t0 = this.now(), this.t = 0, this.maxdt = .25
			}, d.Clock.prototype = {
				tick: function() {
					var a = this.now(),
						b = (a - this.t0) / 1e3;
					this.t0 = a, this.t += b, b < this.maxdt && b > 0 && this.ontick(b)
				},
				start: function(a) {
					this.running = !0;
					var b, c = this;
					e ? e(b = function() {
						c.tick(), c.running && e(b, a)
					}, a) : this.interval = window.setInterval(function() {
						c.tick()
					}, 1), this.t0 = this.now()
				},
				stop: function() {
					this.interval && (window.clearInterval(this.interval), this.interval = null), this.running = !1
				},
				now: function() {
					return window.performance.now()
				},
				ontick: function(a) {}
			}, d.fixedstep = function(a, b, c) {
				var d = 0,
					e = 0;
				return function(f) {
					for (d += f; d >= a;) b(a, e), d -= a, f -= a, e += a;
					c(f, e)
				}
			}
		}), define("engine/utils", ["require", "exports", "module"], function(a, b, c) {
			var d = b;
			d.extend = function() {
				var a, b, c, d = arguments[0];
				for (a = 1; a < arguments.length; a++) {
					b = arguments[a];
					for (c in b) d[c] = b[c]
				}
				return d
			}, d.debounce = function(a, b) {
				function c() {
					a.apply(f, d)
				}
				var d, e, f;
				return function() {
					f = this, d = arguments, clearTimeout(e), e = setTimeout(c, b)
				}
			}, d.clamp = function(a, b, c) {
				return b > a ? b : a > c ? c : a
			}, d.getHashValue = function(a, b) {
				var c = window.location.hash.match("[#,]+" + a + "(=([^,]*))?");
				return c ? 3 == c.length && null != c[2] ? c[2] : !0 : b
			}
		}), define("engine/input", ["require", "exports", "module", "engine/utils"], function(a, b, c) {
			var d = b,
				e = a("engine/utils").clamp,
				f = {
					32: "SPACE",
					13: "ENTER",
					9: "TAB",
					8: "BACKSPACE",
					16: "SHIFT",
					17: "CTRL",
					18: "ALT",
					20: "CAPS_LOCK",
					144: "NUM_LOCK",
					145: "SCROLL_LOCK",
					37: "LEFT",
					38: "UP",
					39: "RIGHT",
					40: "DOWN",
					33: "PAGE_UP",
					34: "PAGE_DOWN",
					36: "HOME",
					35: "END",
					45: "INSERT",
					46: "DELETE",
					27: "ESCAPE",
					19: "PAUSE"
				};
			d.Handler = function(a) {
				this.bind(a), this.reset()
			}, d.Handler.prototype = {
				offset: {
					x: 0,
					y: 0
				},
				onClick: null,
				onKeyUp: null,
				onKeyDown: null,
				hasFocus: !0,
				bind: function(a) {
					var b = this;
					this.element = a, this.updateOffset(), document.addEventListener("keydown", function(a) {
						!b.keyDown(a.keyCode)
					}), document.addEventListener("keyup", function(a) {
						!b.keyUp(a.keyCode)
					}), window.addEventListener("click", function(c) {
						c.target != a ? b.blur() : b.focus()
					}), window.addEventListener("blur", function(a) {
						b.blur()
					}), document.addEventListener("mousemove", function(a) {
						b.mouseMove(a.clientX, a.clientY)
					}), a.addEventListener("mousedown", function(a) {
						b.mouseDown()
					}), a.addEventListener("mouseup", function(a) {
						b.mouseUp()
					}), document.addEventListener("selectstart", function(a) {})
				},
				updateOffset: function() {
					var a = this.element.getBoundingClientRect();
					this.offset = {
						x: a.left,
						y: a.top
					}
				},
				blur: function() {
					this.hasFocus = !1, this.reset()
				},
				focus: function() {
					this.hasFocus || (this.hasFocus = !0, this.reset())
				},
				reset: function() {
					this.keys = {};
					for (var a = 65; 128 > a; a++) this.keys[String.fromCharCode(a)] = !1;
					for (a in f) f.hasOwnProperty(a) && (this.keys[f[a]] = !1);
					this.mouse = {
						down: !1,
						x: 0,
						y: 0
					}
				},
				keyDown: function(a) {
					var b = this._getKeyName(a),
						c = this.keys[b];
					return this.keys[b] = !0, this.onKeyDown && !c && this.onKeyDown(b), this.hasFocus
				},
				keyUp: function(a) {
					var b = this._getKeyName(a);
					return this.keys[b] = !1, this.onKeyUp && this.onKeyUp(b), this.hasFocus
				},
				mouseDown: function() {
					this.mouse.down = !0
				},
				mouseUp: function() {
					this.mouse.down = !1, this.hasFocus && this.onClick && this.onClick(this.mouse.x, this.mouse.y)
				},
				mouseMove: function(a, b) {
					this.mouse.x = e(a - this.offset.x, 0, window.outerWidth), this.mouse.y = e(b - this.offset.y, 0, window.outerHeight)
				},
				_getKeyName: function(a) {
					return a in f ? f[a] : String.fromCharCode(a)
				}
			}
		}), define("engine/gl/shader", ["require", "exports", "module"], function(a, b, c) {
			function d(a) {
				var b = [];
				for (var c in a) b.push(c);
				return b
			}

			function e(a, b, c) {
				this.gl = a, this.program = this.makeProgram(b, c), this.uniformLocations = {}, this.uniformValues = {}, this.uniformNames = [], this.attributeLocations = {}
			}
			e.prototype = {
				use: function() {
					this.gl.useProgram(this.program)
				},
				prepareUniforms: function(a) {
					this.uniformNames = d(a);
					for (var b = 0; b < this.uniformNames.length; b++) {
						var c = this.uniformNames[b];
						this.uniformLocations[c] = this.gl.getUniformLocation(this.program, c)
					}
				},
				uniforms: function(a) {
					0 === this.uniformNames.length && this.prepareUniforms(a);
					for (var b = 0; b < this.uniformNames.length; b++) {
						var c = this.uniformNames[b],
							d = this.uniformLocations[c],
							e = a[c];
						if (null !== d)
							if (e.uniform) e.equals(this.uniformValues[c]) || (e.uniform(d), e.set(this.uniformValues, c));
							else if (e.length) {
							var f = this.uniformValues[c];
							if (void 0 !== f) {
								for (var g = 0, h = e.length; h > g && e[g] == f[g]; g++);
								if (g != h)
									for (g = 0, h = e.length; h > g; g++) f[g] = e[g]
							} else this.uniformValues[c] = new Float32Array(e);
							switch (e.length) {
								case 2:
									this.gl.uniform2fv(d, e);
									break;
								case 3:
									this.gl.uniform3fv(d, e);
									break;
								case 4:
									this.gl.uniform4fv(d, e);
									break;
								case 9:
									this.gl.uniformMatrix3fv(d, !1, e);
									break;
								case 16:
									this.gl.uniformMatrix4fv(d, !1, e)
							}
						} else e != this.uniformValues[c] && (this.gl.uniform1f(d, e), this.uniformValues[c] = e)
					}
				},
				getUniformLocation: function(a) {
					return void 0 === this.uniformLocations[a] && (this.uniformLocations[a] = this.gl.getUniformLocation(this.program, a)), this.uniformLocations[a]
				},
				getAttribLocation: function(a) {
					if (!(a in this.attributeLocations)) {
						var b = this.gl.getAttribLocation(this.program, a);
						if (0 > b) throw "undefined attribute " + a;
						this.attributeLocations[a] = b
					}
					return this.attributeLocations[a]
				},
				makeShader: function(a, b) {
					var c = this.gl.createShader(a);
					if (this.gl.shaderSource(c, b), this.gl.compileShader(c), !this.gl.getShaderParameter(c, this.gl.COMPILE_STATUS)) throw console.log(this.gl.getShaderInfoLog(c), a, b), 'Compiler exception: "' + this.gl.getShaderInfoLog(c) + '"';
					return c
				},
				makeProgram: function(a, b) {
					var c = this.makeShader(this.gl.VERTEX_SHADER, a),
						d = this.makeShader(this.gl.FRAGMENT_SHADER, b),
						e = this.gl.createProgram();
					if (this.gl.attachShader(e, c), this.gl.attachShader(e, d), this.gl.linkProgram(e), !this.gl.getProgramParameter(e, this.gl.LINK_STATUS)) throw "Linker exception: " + this.gl.getProgramInfoLog(e);
					return e
				}
			}, b.Shader = e, b.Manager = function(a, b, c) {
				this.gl = a, this.resources = b, this.shaders = [], c = c || {}, this.prefix = c.prefix || "shaders/"
			}, b.Manager.prototype = {
				includeExpression: /#include "([^"]+)"/g,
				preprocess: function(a, b) {
					return b.replace(this.includeExpression, function(a, b) {
						return this.getSource(b)
					}.bind(this))
				},
				getSource: function(a) {
					var b = this.resources[this.prefix + a];
					if (null == b) throw "shader not found: " + a;
					return this.preprocess(a, b)
				},
				get: function(a, b) {
					b || (b = a), b += ".frag", a += ".vertex";
					var c = b + ";" + a;
					return c in this.shaders || (this.shaders[c] = new e(this.gl, this.getSource(a), this.getSource(b))), this.shaders[c]
				}
			}
		}), define("engine/gl/geometry", ["require", "exports", "module"], function(a, b, c) {
			b.grid = function(a) {
				for (var b = new Float32Array(a * a * 6 * 3), c = 0, d = 0; a > d; d++)
					for (var e = 0; a > e; e++) b[c++] = e / a, b[c++] = 0, b[c++] = d / a, b[c++] = e / a, b[c++] = 0, b[c++] = (d + 1) / a, b[c++] = (e + 1) / a, b[c++] = 0, b[c++] = (d + 1) / a, b[c++] = e / a, b[c++] = 0, b[c++] = d / a, b[c++] = (e + 1) / a, b[c++] = 0, b[c++] = (d + 1) / a, b[c++] = (e + 1) / a, b[c++] = 0, b[c++] = d / a;
				return b
			}, b.wireFrame = function(a) {
				for (var b = new Float32Array(2 * a.length), c = a.length / 9, d = 0; c > d; d++)
					for (var e = 0; 3 > e; e++)
						for (var f = (e + 1) % 3, g = 0; 3 > g; g++) b[18 * d + 3 * e + g] = a[9 * d + 3 * e + g], b[18 * d + 3 * e + 9 + g] = a[9 * d + 3 * f + g];
				return b
			}, b.screen_quad = function(a, b) {
				return a = a || 1, b = b || a, new Float32Array([-a, b, 0, -a, -b, 0, a, -b, 0, -a, b, 0, a, -b, 0, a, b, 0])
			}, b.cube = function(a) {
				return a = a || 1, new Float32Array([a, a, a, a, -a, a, -a, -a, a, a, a, a, -a, -a, a, -a, a, a, -a, a, -a, -a, -a, -a, a, a, -a, a, a, -a, -a, -a, -a, a, -a, -a, -a, a, a, -a, -a, -a, -a, a, -a, -a, a, a, -a, -a, a, -a, -a, -a, a, a, a, a, a, -a, a, -a, -a, a, a, a, a, -a, -a, a, -a, a, a, a, a, -a, a, a, -a, a, -a, a, a, -a, a, a, a, -a, a, -a, -a, -a, -a, -a, -a, a, a, -a, a, -a, -a, -a, a, -a, a, a, -a, -a])
			}
		}), define("engine/gl/texture", ["require", "exports", "module", "../utils"], function(a, b, c) {
			var d = a("../utils").extend;
			b.Texture2D = function(a, b, c) {
				this.gl = a, this.texture = a.createTexture(), this.unit = -1, this.bound = !1, this.bindTexture(), a.pixelStorei(a.UNPACK_FLIP_Y_WEBGL, !1), a.pixelStorei(a.UNPACK_PREMULTIPLY_ALPHA_WEBGL, !1), a.pixelStorei(a.UNPACK_COLORSPACE_CONVERSION_WEBGL, a.NONE), a.texImage2D(a.TEXTURE_2D, 0, c.internalformat || c.format || a.RGBA, c.format || a.RGBA, c.type || a.UNSIGNED_BYTE, b), a.texParameteri(a.TEXTURE_2D, a.TEXTURE_MAG_FILTER, c.mag_filter || a.LINEAR), a.texParameteri(a.TEXTURE_2D, a.TEXTURE_MIN_FILTER, c.min_filter || a.LINEAR_MIPMAP_LINEAR), a.texParameterf(a.TEXTURE_2D, a.TEXTURE_WRAP_S, c.wrap_s || a.REPEAT), a.texParameterf(a.TEXTURE_2D, a.TEXTURE_WRAP_T, c.wrap_t || a.REPEAT), c.mipmap !== !1 && a.generateMipmap(a.TEXTURE_2D)
			}, b.Texture2D.prototype = {
				bindTexture: function(a) {
					void 0 !== a && (this.gl.activeTexture(this.gl.TEXTURE0 + a), this.unit = a), this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture), this.bound = !0
				},
				unbindTexture: function() {
					this.gl.activeTexture(this.gl.TEXTURE0 + this.unit), this.gl.bindTexture(this.gl.TEXTURE_2D, null), this.unit = -1, this.bound = !1
				},
				uniform: function(a) {
					this.gl.uniform1i(a, this.unit)
				},
				equals: function(a) {
					return this.unit === a
				},
				set: function(a, b) {
					a[b] = this.unit
				}
			}, b.FBO = function(a, b, c, d, e) {
				this.width = b, this.height = c, this.gl = a, this.framebuffer = a.createFramebuffer(), a.bindFramebuffer(a.FRAMEBUFFER, this.framebuffer), this.texture = a.createTexture(), a.bindTexture(a.TEXTURE_2D, this.texture), a.texImage2D(a.TEXTURE_2D, 0, e || a.RGBA, b, c, 0, e || a.RGBA, d || a.UNSIGNED_BYTE, null), a.texParameteri(a.TEXTURE_2D, a.TEXTURE_MAG_FILTER, a.LINEAR), a.texParameteri(a.TEXTURE_2D, a.TEXTURE_MIN_FILTER, a.LINEAR), a.texParameteri(a.TEXTURE_2D, a.TEXTURE_WRAP_S, a.CLAMP_TO_EDGE), a.texParameteri(a.TEXTURE_2D, a.TEXTURE_WRAP_T, a.CLAMP_TO_EDGE), this.depth = a.createRenderbuffer(), a.bindRenderbuffer(a.RENDERBUFFER, this.depth), a.renderbufferStorage(a.RENDERBUFFER, a.DEPTH_COMPONENT16, b, c), a.framebufferTexture2D(a.FRAMEBUFFER, a.COLOR_ATTACHMENT0, a.TEXTURE_2D, this.texture, 0), a.framebufferRenderbuffer(a.FRAMEBUFFER, a.DEPTH_ATTACHMENT, a.RENDERBUFFER, this.depth), this.supported = a.checkFramebufferStatus(a.FRAMEBUFFER) === a.FRAMEBUFFER_COMPLETE, a.bindTexture(a.TEXTURE_2D, null), a.bindRenderbuffer(a.RENDERBUFFER, null), a.bindFramebuffer(a.FRAMEBUFFER, null), this.unit = -1
			}, b.FBO.prototype = d({}, b.Texture2D.prototype, {
				bind: function() {
					this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer)
				},
				unbind: function() {
					this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null)
				}
			})
		}), define("engine/gl/mesh", ["require", "exports", "module"], function(a, b, c) {
			var d = function(a, b) {
				if (this.gl = a, this.ibo = b.ibo, this.vbo = b.vbo || new e(a, b.vertex), this.mode = b.mode || a.TRIANGLES, this.ibo) switch (this.ibo.byteLength / this.ibo.length) {
					case 1:
						this.iboType = a.UNSIGNED_BYTE;
						break;
					case 2:
						this.iboType = a.UNSIGNED_SHORT;
						break;
					case 4:
						this.iboType = a.UNSIGNED_LONG;
						break;
					default:
						this.iboType = a.UNSIGNED_SHORT
				} else this.iboType = 0;
				this.setAttributes(b.attributes)
			};
			d.prototype = {
				setAttributes: function(a) {
					var b = Object.keys(a);
					this.attributes = [], this.vertexSize = 0;
					for (var c = 0; c < b.length; c++) {
						var d = b[c],
							e = a[d],
							f = {
								name: d,
								size: e.size || 3,
								type: e.type || this.gl.FLOAT,
								stride: e.stride || 0,
								offset: e.offset || 0,
								normalized: !!e.normalized
							};
						this.vertexSize += f.size, this.attributes.push(f)
					}
				},
				bindAttributes: function(a) {
					for (var b = 0; b < this.attributes.length; b++) {
						var c = this.attributes[b],
							d = a.getAttribLocation(c.name);
						this.gl.enableVertexAttribArray(d), this.gl.vertexAttribPointer(d, c.size, c.type, c.normalized, c.stride, c.offset)
					}
				},
				draw: function(a) {
					a.use(), this.vbo.bind(), this.bindAttributes(a), this.ibo ? (this.ibo.bind(), this.gl.drawElements(this.mode, this.ibo.length, this.iboType, 0)) : this.gl.drawArrays(this.mode, 0, this.vbo.length / this.vertexSize), this.vbo.unbind()
				}
			}, b.Mesh = d;
			var e = function(a, b, c, d) {
				this.gl = a, this.target = c || a.ARRAY_BUFFER, this.buffer = a.createBuffer(), this.bind(), a.bufferData(a.ARRAY_BUFFER, b, d || a.STATIC_DRAW), this.unbind(), this.length = b.length, this.btyeLength = b.byteLength
			};
			e.prototype = {
				bind: function() {
					this.gl.bindBuffer(this.target, this.buffer)
				},
				unbind: function() {
					this.gl.bindBuffer(this.target, null)
				},
				free: function(a) {
					this.gl.deleteBuffer(this.buffer), delete this.buffer
				}
			}, b.Buffer = e
		}), WebGLDebugUtils = function() {
			function a(a) {
				if (null == n) {
					n = {};
					for (var b in a) "number" == typeof a[b] && (n[a[b]] = b)
				}
			}

			function b() {
				if (null == n) throw "WebGLDebugUtils.init(ctx) not called"
			}

			function c(a) {
				return b(), void 0 !== n[a]
			}

			function d(a) {
				b();
				var c = n[a];
				return void 0 !== c ? c : "*UNKNOWN WebGL ENUM (0x" + a.toString(16) + ")"
			}

			function e(a, b, c) {
				var e = m[a];
				return void 0 !== e && e[b] ? d(c) : null === c ? "null" : void 0 === c ? "undefined" : c.toString()
			}

			function f(a, b) {
				for (var c = "", d = 0; d < b.length; ++d) c += (0 == d ? "" : ", ") + e(a, d, b[d]);
				return c
			}

			function g(a, b, c) {
				a.__defineGetter__(c, function() {
					return b[c]
				}), a.__defineSetter__(c, function(a) {
					b[c] = a
				})
			}

			function h(b, c, f) {
				function h(a, b) {
					return function() {
						f && f(b, arguments);
						var d = a[b].apply(a, arguments),
							e = a.getError();
						return 0 != e && (i[e] = !0, c(e, b, arguments)), d
					}
				}
				a(b), c = c || function(a, b, c) {
					for (var f = "", g = 0; g < c.length; ++g) f += (0 == g ? "" : ", ") + e(b, g, c[g]);
					l("WebGL error " + d(a) + " in " + b + "(" + f + ")")
				};
				var i = {},
					j = {};
				for (var k in b) "function" == typeof b[k] ? j[k] = h(b, k) : g(j, b, k);
				return j.getError = function() {
					for (var a in i)
						if (i.hasOwnProperty(a) && i[a]) return i[a] = !1, a;
					return b.NO_ERROR
				}, j
			}

			function i(a) {
				var b = a.getParameter(a.MAX_VERTEX_ATTRIBS),
					c = a.createBuffer();
				a.bindBuffer(a.ARRAY_BUFFER, c);
				for (var d = 0; b > d; ++d) a.disableVertexAttribArray(d), a.vertexAttribPointer(d, 4, a.FLOAT, !1, 0, 0), a.vertexAttrib1f(d, 0);
				a.deleteBuffer(c);
				for (var e = a.getParameter(a.MAX_TEXTURE_IMAGE_UNITS), d = 0; e > d; ++d) a.activeTexture(a.TEXTURE0 + d), a.bindTexture(a.TEXTURE_CUBE_MAP, null), a.bindTexture(a.TEXTURE_2D, null);
				for (a.activeTexture(a.TEXTURE0), a.useProgram(null), a.bindBuffer(a.ARRAY_BUFFER, null), a.bindBuffer(a.ELEMENT_ARRAY_BUFFER, null), a.bindFramebuffer(a.FRAMEBUFFER, null), a.bindRenderbuffer(a.RENDERBUFFER, null), a.disable(a.BLEND), a.disable(a.CULL_FACE), a.disable(a.DEPTH_TEST), a.disable(a.DITHER), a.disable(a.SCISSOR_TEST), a.blendColor(0, 0, 0, 0), a.blendEquation(a.FUNC_ADD), a.blendFunc(a.ONE, a.ZERO), a.clearColor(0, 0, 0, 0), a.clearDepth(1), a.clearStencil(-1), a.colorMask(!0, !0, !0, !0), a.cullFace(a.BACK), a.depthFunc(a.LESS), a.depthMask(!0), a.depthRange(0, 1), a.frontFace(a.CCW), a.hint(a.GENERATE_MIPMAP_HINT, a.DONT_CARE), a.lineWidth(1), a.pixelStorei(a.PACK_ALIGNMENT, 4), a.pixelStorei(a.UNPACK_ALIGNMENT, 4), a.pixelStorei(a.UNPACK_FLIP_Y_WEBGL, !1), a.pixelStorei(a.UNPACK_PREMULTIPLY_ALPHA_WEBGL, !1), a.UNPACK_COLORSPACE_CONVERSION_WEBGL && a.pixelStorei(a.UNPACK_COLORSPACE_CONVERSION_WEBGL, a.BROWSER_DEFAULT_WEBGL), a.polygonOffset(0, 0), a.sampleCoverage(1, !1), a.scissor(0, 0, a.canvas.width, a.canvas.height), a.stencilFunc(a.ALWAYS, 0, 4294967295), a.stencilMask(4294967295), a.stencilOp(a.KEEP, a.KEEP, a.KEEP), a.viewport(0, 0, a.canvas.width, a.canvas.height), a.clear(a.COLOR_BUFFER_BIT | a.DEPTH_BUFFER_BIT | a.STENCIL_BUFFER_BIT); a.getError(););
			}

			function j(a) {
				function b(a) {
					return "function" == typeof a ? a : function(b) {
						a.handleEvent(b)
					}
				}

				function c(a) {
					var b = a.addEventListener;
					a.addEventListener = function(c, d, e) {
						switch (c) {
							case "webglcontextlost":
								x(d);
								break;
							case "webglcontextrestored":
								y(d);
								break;
							default:
								b.apply(a, arguments)
						}
					}
				}

				function d() {
					for (var a = Object.keys(w), b = 0; b < a.length; ++b) delete w[a]
				}

				function e() {
					++t, q || s == t && a.loseContext()
				}

				function f(a, b) {
					var c = a[b];
					return function() {
						if (e(), !q) {
							var b = c.apply(a, arguments);
							return b
						}
					}
				}

				function h() {
					for (var a = 0; a < r.length; ++a) {
						var b = r[a];
						b instanceof WebGLBuffer ? l.deleteBuffer(b) : b instanceof WebGLFramebuffer ? l.deleteFramebuffer(b) : b instanceof WebGLProgram ? l.deleteProgram(b) : b instanceof WebGLRenderbuffer ? l.deleteRenderbuffer(b) : b instanceof WebGLShader ? l.deleteShader(b) : b instanceof WebGLTexture && l.deleteTexture(b)
					}
				}

				function j(a) {
					return {
						statusMessage: a,
						preventDefault: function() {
							u = !0
						}
					}
				}

				function k(a) {
					for (var b in a) "function" == typeof a[b] ? m[b] = f(a, b) : g(m, a, b);
					m.getError = function() {
						if (e(), !q)
							for (var a; a = l.getError();) w[a] = !0;
						for (var a in w)
							if (w[a]) return delete w[a], a;
						return m.NO_ERROR
					};
					for (var c = ["createBuffer", "createFramebuffer", "createProgram", "createRenderbuffer", "createShader", "createTexture"], d = 0; d < c.length; ++d) {
						var h = c[d];
						m[h] = function(b) {
							return function() {
								if (e(), q) return null;
								var c = b.apply(a, arguments);
								return c.__webglDebugContextLostId__ = p, r.push(c), c
							}
						}(a[h])
					}
					for (var i = ["getActiveAttrib", "getActiveUniform", "getBufferParameter", "getContextAttributes", "getAttachedShaders", "getFramebufferAttachmentParameter", "getParameter", "getProgramParameter", "getProgramInfoLog", "getRenderbufferParameter", "getShaderParameter", "getShaderInfoLog", "getShaderSource", "getTexParameter", "getUniform", "getUniformLocation", "getVertexAttrib"], d = 0; d < i.length; ++d) {
						var h = i[d];
						m[h] = function(b) {
							return function() {
								return e(), q ? null : b.apply(a, arguments)
							}
						}(m[h])
					}
					for (var j = ["isBuffer", "isEnabled", "isFramebuffer", "isProgram", "isRenderbuffer", "isShader", "isTexture"], d = 0; d < j.length; ++d) {
						var h = j[d];
						m[h] = function(b) {
							return function() {
								return e(), q ? !1 : b.apply(a, arguments)
							}
						}(m[h])
					}
					return m.checkFramebufferStatus = function(b) {
						return function() {
							return e(), q ? m.FRAMEBUFFER_UNSUPPORTED : b.apply(a, arguments)
						}
					}(m.checkFramebufferStatus), m.getAttribLocation = function(b) {
						return function() {
							return e(), q ? -1 : b.apply(a, arguments)
						}
					}(m.getAttribLocation), m.getVertexAttribOffset = function(b) {
						return function() {
							return e(), q ? 0 : b.apply(a, arguments)
						}
					}(m.getVertexAttribOffset), m.isContextLost = function() {
						return q
					}, m
				}
				var l, m, n = [],
					o = [],
					m = {},
					p = 1,
					q = !1,
					r = [],
					s = 0,
					t = 0,
					u = !1,
					v = 0,
					w = {};
				a.getContext = function(b) {
					return function() {
						var c = b.apply(a, arguments);
						if (c instanceof WebGLRenderingContext) {
							if (c != l) {
								if (l) throw "got different context";
								l = c, m = k(l)
							}
							return m
						}
						return c
					}
				}(a.getContext);
				var x = function(a) {
						n.push(b(a))
					},
					y = function(a) {
						o.push(b(a))
					};
				return c(a), a.loseContext = function() {
					if (!q) {
						for (q = !0, s = 0, ++p; l.getError(););
						d(), w[l.CONTEXT_LOST_WEBGL] = !0;
						var b = j("context lost"),
							c = n.slice();
						setTimeout(function() {
							for (var d = 0; d < c.length; ++d) c[d](b);
							v >= 0 && setTimeout(function() {
								a.restoreContext()
							}, v)
						}, 0)
					}
				}, a.restoreContext = function() {
					q && o.length && setTimeout(function() {
						if (!u) throw "can not restore. webglcontestlost listener did not call event.preventDefault";
						h(), i(l), q = !1, t = 0, u = !1;
						for (var a = o.slice(), b = j("context restored"), c = 0; c < a.length; ++c) a[c](b)
					}, 0)
				}, a.loseContextInNCalls = function(a) {
					if (q) throw "You can not ask a lost contet to be lost";
					s = t + a
				}, a.getNumCalls = function() {
					return t
				}, a.setRestoreTimeout = function(a) {
					v = a
				}, a
			}
			var k = function(a) {
					window.console && window.console.log && window.console.log(a)
				},
				l = function(a) {
					window.console && window.console.error ? window.console.error(a) : k(a)
				},
				m = {
					enable: {
						0: !0
					},
					disable: {
						0: !0
					},
					getParameter: {
						0: !0
					},
					drawArrays: {
						0: !0
					},
					drawElements: {
						0: !0,
						2: !0
					},
					createShader: {
						0: !0
					},
					getShaderParameter: {
						1: !0
					},
					getProgramParameter: {
						1: !0
					},
					getVertexAttrib: {
						1: !0
					},
					vertexAttribPointer: {
						2: !0
					},
					bindTexture: {
						0: !0
					},
					activeTexture: {
						0: !0
					},
					getTexParameter: {
						0: !0,
						1: !0
					},
					texParameterf: {
						0: !0,
						1: !0
					},
					texParameteri: {
						0: !0,
						1: !0,
						2: !0
					},
					texImage2D: {
						0: !0,
						2: !0,
						6: !0,
						7: !0
					},
					texSubImage2D: {
						0: !0,
						6: !0,
						7: !0
					},
					copyTexImage2D: {
						0: !0,
						2: !0
					},
					copyTexSubImage2D: {
						0: !0
					},
					generateMipmap: {
						0: !0
					},
					bindBuffer: {
						0: !0
					},
					bufferData: {
						0: !0,
						2: !0
					},
					bufferSubData: {
						0: !0
					},
					getBufferParameter: {
						0: !0,
						1: !0
					},
					pixelStorei: {
						0: !0,
						1: !0
					},
					readPixels: {
						4: !0,
						5: !0
					},
					bindRenderbuffer: {
						0: !0
					},
					bindFramebuffer: {
						0: !0
					},
					checkFramebufferStatus: {
						0: !0
					},
					framebufferRenderbuffer: {
						0: !0,
						1: !0,
						2: !0
					},
					framebufferTexture2D: {
						0: !0,
						1: !0,
						2: !0
					},
					getFramebufferAttachmentParameter: {
						0: !0,
						1: !0,
						2: !0
					},
					getRenderbufferParameter: {
						0: !0,
						1: !0
					},
					renderbufferStorage: {
						0: !0,
						1: !0
					},
					clear: {
						0: !0
					},
					depthFunc: {
						0: !0
					},
					blendFunc: {
						0: !0,
						1: !0
					},
					blendFuncSeparate: {
						0: !0,
						1: !0,
						2: !0,
						3: !0
					},
					blendEquation: {
						0: !0
					},
					blendEquationSeparate: {
						0: !0,
						1: !0
					},
					stencilFunc: {
						0: !0
					},
					stencilFuncSeparate: {
						0: !0,
						1: !0
					},
					stencilMaskSeparate: {
						0: !0
					},
					stencilOp: {
						0: !0,
						1: !0,
						2: !0
					},
					stencilOpSeparate: {
						0: !0,
						1: !0,
						2: !0,
						3: !0
					},
					cullFace: {
						0: !0
					},
					frontFace: {
						0: !0
					}
				},
				n = null;
			return {
				init: a,
				mightBeEnum: c,
				glEnumToString: d,
				glFunctionArgToString: e,
				glFunctionArgsToString: f,
				makeDebugContext: h,
				makeLostContextSimulatingCanvas: j,
				resetToInitialState: i
			}
		}(), define("engine/gl/_webgl-debug", function() {}), define("engine/gl/context", ["require", "exports", "module", "./mesh", "./texture", "../utils", "./shader", "./_webgl-debug"], function(a, b, c) {
			function d(a, b, c) {
				window.console && window.console.error && console.error(c, b)
			}
			var e = a("./mesh"),
				f = a("./texture"),
				g = a("../utils").extend,
				h = a("./shader");
			a("./_webgl-debug"), b.Context = function(a, b) {
				this.gl = a, this.resources = b, this.shaderManager = new h.Manager(b)
			}, b.Context.prototype = {
				getBuffer: function(a, b, c) {
					var d = this.resources[a];
					new e.Buffer(this.gl, d, b, c)
				},
				getFBO: function() {},
				getTexture: function(a, b) {
					var c = this.resources[a];
					return new f.Texture2D(this.gl, c, b)
				},
				getShader: function(a) {}
			}, b.initialize = function(a, b, c) {
				var e = "Try upgrading to the latest version of firefox or chrome.";
				if (c = c || d, !a.getContext) return void c(a, "canvas is not supported by your browser. " + e, "no-canvas");
				var f = g({
						alpha: !1,
						depth: !0,
						stencil: !1,
						antialias: !0,
						premultipliedAlpha: !1,
						preserveDrawingBuffer: !1
					}, b.context),
					h = b.extensions || {},
					i = a.getContext("webgl", f);
				return null == i && (i = a.getContext("experimental-webgl", f), null == i) ? void c(a, "webgl is not supported by your browser. " + e, "no-webgl") : b.vertex_texture_units && i.getParameter(i.MAX_VERTEX_TEXTURE_IMAGE_UNITS) < b.vertex_texture_units ? void c(a, "This application needs at least two vertex texture units which are not supported by your browser. " + e, "no-vertext-texture-units") : h.texture_float && null == i.getExtension("OES_texture_float") ? void c(a, "This application needs float textures which is not supported by your browser. " + e, "no-OES_texture_float") : (h.standard_derivatives && null == i.getExtension("OES_standard_derivatives") && c(a, "This application need the standard deriviates extensions for WebGL which is not supported by your Browser." + e, "no-OES_standard_derivatives"), window.WebGLDebugUtils && b.debug && (i = b.log_all ? WebGLDebugUtils.makeDebugContext(i, void 0, function() {
					console.log.apply(console, arguments)
				}) : WebGLDebugUtils.makeDebugContext(i), console.log("running in debug context")), f.depth ? i.enable(i.DEPTH_TEST) : i.disable(i.DEPTH_TEST), i.enable(i.CULL_FACE), i.lost = !1, a.addEventListener("webglcontextlost", function() {
					c(a, "Lost webgl context!", "context-lost"), i.lost = !0
				}, !1), i)
			}
		}),
		function(a, b) {
			"object" == typeof exports ? module.exports = b(global) : "function" == typeof define && define.amd ? define("gl-matrix", [], function() {
				return b(a)
			}) : b(a)
		}(this, function(a) {
			function b(a) {
				return f = a
			}

			function c() {
				return f = "undefined" != typeof Float32Array ? Float32Array : Array
			}
			var d = 1e-6,
				e = {};
			! function() {
				if ("undefined" != typeof Float32Array) {
					var a = new Float32Array(1),
						b = new Int32Array(a.buffer);
					e.invsqrt = function(c) {
						var d = .5 * c;
						a[0] = c;
						var e = 1.5;
						b[0] = 1597463007 - (b[0] >> 1);
						var f = a[0];
						return f * (e - d * f * f)
					}
				} else e.invsqrt = function(a) {
					return 1 / Math.sqrt(a)
				}
			}();
			var f = null;
			c();
			var g = {};
			g.create = function(a) {
				var b = new f(3);
				return a ? (b[0] = a[0], b[1] = a[1], b[2] = a[2]) : b[0] = b[1] = b[2] = 0, b
			}, g.createFrom = function(a, b, c) {
				var d = new f(3);
				return d[0] = a, d[1] = b, d[2] = c, d
			}, g.set = function(a, b) {
				return b[0] = a[0], b[1] = a[1], b[2] = a[2], b
			}, g.equal = function(a, b) {
				return a === b || Math.abs(a[0] - b[0]) < d && Math.abs(a[1] - b[1]) < d && Math.abs(a[2] - b[2]) < d
			}, g.add = function(a, b, c) {
				return c && a !== c ? (c[0] = a[0] + b[0], c[1] = a[1] + b[1], c[2] = a[2] + b[2], c) : (a[0] += b[0], a[1] += b[1], a[2] += b[2], a)
			}, g.subtract = function(a, b, c) {
				return c && a !== c ? (c[0] = a[0] - b[0], c[1] = a[1] - b[1], c[2] = a[2] - b[2], c) : (a[0] -= b[0], a[1] -= b[1], a[2] -= b[2], a)
			}, g.multiply = function(a, b, c) {
				return c && a !== c ? (c[0] = a[0] * b[0], c[1] = a[1] * b[1], c[2] = a[2] * b[2], c) : (a[0] *= b[0], a[1] *= b[1], a[2] *= b[2], a)
			}, g.negate = function(a, b) {
				return b || (b = a), b[0] = -a[0], b[1] = -a[1], b[2] = -a[2], b
			}, g.scale = function(a, b, c) {
				return c && a !== c ? (c[0] = a[0] * b, c[1] = a[1] * b, c[2] = a[2] * b, c) : (a[0] *= b, a[1] *= b, a[2] *= b, a)
			}, g.normalize = function(a, b) {
				b || (b = a);
				var c = a[0],
					d = a[1],
					e = a[2],
					f = Math.sqrt(c * c + d * d + e * e);
				return f ? 1 === f ? (b[0] = c, b[1] = d, b[2] = e, b) : (f = 1 / f, b[0] = c * f, b[1] = d * f, b[2] = e * f, b) : (b[0] = 0, b[1] = 0, b[2] = 0, b)
			}, g.cross = function(a, b, c) {
				c || (c = a);
				var d = a[0],
					e = a[1],
					f = a[2],
					g = b[0],
					h = b[1],
					i = b[2];
				return c[0] = e * i - f * h, c[1] = f * g - d * i, c[2] = d * h - e * g, c
			}, g.length = function(a) {
				var b = a[0],
					c = a[1],
					d = a[2];
				return Math.sqrt(b * b + c * c + d * d)
			}, g.squaredLength = function(a) {
				var b = a[0],
					c = a[1],
					d = a[2];
				return b * b + c * c + d * d
			}, g.dot = function(a, b) {
				return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
			}, g.direction = function(a, b, c) {
				c || (c = a);
				var d = a[0] - b[0],
					e = a[1] - b[1],
					f = a[2] - b[2],
					g = Math.sqrt(d * d + e * e + f * f);
				return g ? (g = 1 / g, c[0] = d * g, c[1] = e * g, c[2] = f * g, c) : (c[0] = 0, c[1] = 0, c[2] = 0, c)
			}, g.lerp = function(a, b, c, d) {
				return d || (d = a), d[0] = a[0] + c * (b[0] - a[0]), d[1] = a[1] + c * (b[1] - a[1]), d[2] = a[2] + c * (b[2] - a[2]), d
			}, g.dist = function(a, b) {
				var c = b[0] - a[0],
					d = b[1] - a[1],
					e = b[2] - a[2];
				return Math.sqrt(c * c + d * d + e * e)
			};
			var h = null,
				i = new f(4);
			g.unproject = function(a, b, c, d, e) {
				e || (e = a), h || (h = o.create());
				var f = h,
					g = i;
				return g[0] = 2 * (a[0] - d[0]) / d[2] - 1, g[1] = 2 * (a[1] - d[1]) / d[3] - 1, g[2] = 2 * a[2] - 1, g[3] = 1, o.multiply(c, b, f), o.inverse(f) ? (o.multiplyVec4(f, g), 0 === g[3] ? null : (e[0] = g[0] / g[3], e[1] = g[1] / g[3], e[2] = g[2] / g[3], e)) : null
			};
			var j = g.createFrom(1, 0, 0),
				k = g.createFrom(0, 1, 0),
				l = g.createFrom(0, 0, 1),
				m = g.create();
			g.rotationTo = function(a, b, c) {
				c || (c = p.create());
				var d = g.dot(a, b),
					e = m;
				if (d >= 1) p.set(q, c);
				else if (1e-6 - 1 > d) g.cross(j, a, e), g.length(e) < 1e-6 && g.cross(k, a, e), g.length(e) < 1e-6 && g.cross(l, a, e), g.normalize(e), p.fromAngleAxis(Math.PI, e, c);
				else {
					var f = Math.sqrt(2 * (1 + d)),
						h = 1 / f;
					g.cross(a, b, e), c[0] = e[0] * h, c[1] = e[1] * h, c[2] = e[2] * h, c[3] = .5 * f, p.normalize(c)
				}
				return c[3] > 1 ? c[3] = 1 : c[3] < -1 && (c[3] = -1), c
			}, g.str = function(a) {
				return "[" + a[0] + ", " + a[1] + ", " + a[2] + "]"
			};
			var n = {};
			n.create = function(a) {
				var b = new f(9);
				return a ? (b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3], b[4] = a[4], b[5] = a[5], b[6] = a[6], b[7] = a[7], b[8] = a[8]) : b[0] = b[1] = b[2] = b[3] = b[4] = b[5] = b[6] = b[7] = b[8] = 0, b
			}, n.createFrom = function(a, b, c, d, e, g, h, i, j) {
				var k = new f(9);
				return k[0] = a, k[1] = b, k[2] = c, k[3] = d, k[4] = e, k[5] = g, k[6] = h, k[7] = i, k[8] = j, k
			}, n.determinant = function(a) {
				var b = a[0],
					c = a[1],
					d = a[2],
					e = a[3],
					f = a[4],
					g = a[5],
					h = a[6],
					i = a[7],
					j = a[8];
				return b * (j * f - g * i) + c * (-j * e + g * h) + d * (i * e - f * h)
			}, n.inverse = function(a, b) {
				var c, d = a[0],
					e = a[1],
					f = a[2],
					g = a[3],
					h = a[4],
					i = a[5],
					j = a[6],
					k = a[7],
					l = a[8],
					m = l * h - i * k,
					o = -l * g + i * j,
					p = k * g - h * j,
					q = d * m + e * o + f * p;
				return q ? (c = 1 / q, b || (b = n.create()), b[0] = m * c, b[1] = (-l * e + f * k) * c, b[2] = (i * e - f * h) * c, b[3] = o * c, b[4] = (l * d - f * j) * c, b[5] = (-i * d + f * g) * c, b[6] = p * c, b[7] = (-k * d + e * j) * c, b[8] = (h * d - e * g) * c, b) : null
			}, n.multiply = function(a, b, c) {
				c || (c = a);
				var d = a[0],
					e = a[1],
					f = a[2],
					g = a[3],
					h = a[4],
					i = a[5],
					j = a[6],
					k = a[7],
					l = a[8],
					m = b[0],
					n = b[1],
					o = b[2],
					p = b[3],
					q = b[4],
					r = b[5],
					s = b[6],
					t = b[7],
					u = b[8];
				return c[0] = m * d + n * g + o * j, c[1] = m * e + n * h + o * k, c[2] = m * f + n * i + o * l, c[3] = p * d + q * g + r * j, c[4] = p * e + q * h + r * k, c[5] = p * f + q * i + r * l, c[6] = s * d + t * g + u * j, c[7] = s * e + t * h + u * k, c[8] = s * f + t * i + u * l, c
			}, n.multiplyVec2 = function(a, b, c) {
				c || (c = b);
				var d = b[0],
					e = b[1];
				return c[0] = d * a[0] + e * a[3] + a[6], c[1] = d * a[1] + e * a[4] + a[7], c
			}, n.multiplyVec3 = function(a, b, c) {
				c || (c = b);
				var d = b[0],
					e = b[1],
					f = b[2];
				return c[0] = d * a[0] + e * a[3] + f * a[6], c[1] = d * a[1] + e * a[4] + f * a[7], c[2] = d * a[2] + e * a[5] + f * a[8], c
			}, n.set = function(a, b) {
				return b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3], b[4] = a[4], b[5] = a[5], b[6] = a[6], b[7] = a[7], b[8] = a[8], b
			}, n.equal = function(a, b) {
				return a === b || Math.abs(a[0] - b[0]) < d && Math.abs(a[1] - b[1]) < d && Math.abs(a[2] - b[2]) < d && Math.abs(a[3] - b[3]) < d && Math.abs(a[4] - b[4]) < d && Math.abs(a[5] - b[5]) < d && Math.abs(a[6] - b[6]) < d && Math.abs(a[7] - b[7]) < d && Math.abs(a[8] - b[8]) < d
			}, n.identity = function(a) {
				return a || (a = n.create()), a[0] = 1, a[1] = 0, a[2] = 0, a[3] = 0, a[4] = 1, a[5] = 0, a[6] = 0, a[7] = 0, a[8] = 1, a
			}, n.transpose = function(a, b) {
				if (!b || a === b) {
					var c = a[1],
						d = a[2],
						e = a[5];
					return a[1] = a[3], a[2] = a[6], a[3] = c, a[5] = a[7], a[6] = d, a[7] = e, a
				}
				return b[0] = a[0], b[1] = a[3], b[2] = a[6], b[3] = a[1], b[4] = a[4], b[5] = a[7], b[6] = a[2], b[7] = a[5], b[8] = a[8], b
			}, n.toMat4 = function(a, b) {
				return b || (b = o.create()), b[15] = 1, b[14] = 0, b[13] = 0, b[12] = 0, b[11] = 0, b[10] = a[8], b[9] = a[7], b[8] = a[6], b[7] = 0, b[6] = a[5], b[5] = a[4], b[4] = a[3], b[3] = 0, b[2] = a[2], b[1] = a[1], b[0] = a[0], b
			}, n.str = function(a) {
				return "[" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + "]"
			};
			var o = {};
			o.create = function(a) {
				var b = new f(16);
				return a && (b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3], b[4] = a[4], b[5] = a[5], b[6] = a[6], b[7] = a[7], b[8] = a[8], b[9] = a[9], b[10] = a[10], b[11] = a[11], b[12] = a[12], b[13] = a[13], b[14] = a[14], b[15] = a[15]), b
			}, o.createFrom = function(a, b, c, d, e, g, h, i, j, k, l, m, n, o, p, q) {
				var r = new f(16);
				return r[0] = a, r[1] = b, r[2] = c, r[3] = d, r[4] = e, r[5] = g, r[6] = h, r[7] = i, r[8] = j, r[9] = k, r[10] = l, r[11] = m, r[12] = n, r[13] = o, r[14] = p, r[15] = q, r
			}, o.set = function(a, b) {
				return b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3], b[4] = a[4], b[5] = a[5], b[6] = a[6], b[7] = a[7], b[8] = a[8], b[9] = a[9], b[10] = a[10], b[11] = a[11], b[12] = a[12], b[13] = a[13], b[14] = a[14], b[15] = a[15], b
			}, o.equal = function(a, b) {
				return a === b || Math.abs(a[0] - b[0]) < d && Math.abs(a[1] - b[1]) < d && Math.abs(a[2] - b[2]) < d && Math.abs(a[3] - b[3]) < d && Math.abs(a[4] - b[4]) < d && Math.abs(a[5] - b[5]) < d && Math.abs(a[6] - b[6]) < d && Math.abs(a[7] - b[7]) < d && Math.abs(a[8] - b[8]) < d && Math.abs(a[9] - b[9]) < d && Math.abs(a[10] - b[10]) < d && Math.abs(a[11] - b[11]) < d && Math.abs(a[12] - b[12]) < d && Math.abs(a[13] - b[13]) < d && Math.abs(a[14] - b[14]) < d && Math.abs(a[15] - b[15]) < d
			}, o.identity = function(a) {
				return a || (a = o.create()), a[0] = 1, a[1] = 0, a[2] = 0, a[3] = 0, a[4] = 0, a[5] = 1, a[6] = 0, a[7] = 0, a[8] = 0, a[9] = 0, a[10] = 1, a[11] = 0, a[12] = 0, a[13] = 0, a[14] = 0, a[15] = 1, a
			}, o.transpose = function(a, b) {
				if (!b || a === b) {
					var c = a[1],
						d = a[2],
						e = a[3],
						f = a[6],
						g = a[7],
						h = a[11];
					return a[1] = a[4], a[2] = a[8], a[3] = a[12], a[4] = c, a[6] = a[9], a[7] = a[13], a[8] = d, a[9] = f, a[11] = a[14], a[12] = e, a[13] = g, a[14] = h, a
				}
				return b[0] = a[0], b[1] = a[4], b[2] = a[8], b[3] = a[12], b[4] = a[1], b[5] = a[5], b[6] = a[9], b[7] = a[13], b[8] = a[2], b[9] = a[6], b[10] = a[10], b[11] = a[14], b[12] = a[3], b[13] = a[7], b[14] = a[11], b[15] = a[15], b
			}, o.determinant = function(a) {
				var b = a[0],
					c = a[1],
					d = a[2],
					e = a[3],
					f = a[4],
					g = a[5],
					h = a[6],
					i = a[7],
					j = a[8],
					k = a[9],
					l = a[10],
					m = a[11],
					n = a[12],
					o = a[13],
					p = a[14],
					q = a[15];
				return n * k * h * e - j * o * h * e - n * g * l * e + f * o * l * e + j * g * p * e - f * k * p * e - n * k * d * i + j * o * d * i + n * c * l * i - b * o * l * i - j * c * p * i + b * k * p * i + n * g * d * m - f * o * d * m - n * c * h * m + b * o * h * m + f * c * p * m - b * g * p * m - j * g * d * q + f * k * d * q + j * c * h * q - b * k * h * q - f * c * l * q + b * g * l * q
			}, o.inverse = function(a, b) {
				b || (b = a);
				var c, d = a[0],
					e = a[1],
					f = a[2],
					g = a[3],
					h = a[4],
					i = a[5],
					j = a[6],
					k = a[7],
					l = a[8],
					m = a[9],
					n = a[10],
					o = a[11],
					p = a[12],
					q = a[13],
					r = a[14],
					s = a[15],
					t = d * i - e * h,
					u = d * j - f * h,
					v = d * k - g * h,
					w = e * j - f * i,
					x = e * k - g * i,
					y = f * k - g * j,
					z = l * q - m * p,
					A = l * r - n * p,
					B = l * s - o * p,
					C = m * r - n * q,
					D = m * s - o * q,
					E = n * s - o * r,
					F = t * E - u * D + v * C + w * B - x * A + y * z;
				return F ? (c = 1 / F, b[0] = (i * E - j * D + k * C) * c, b[1] = (-e * E + f * D - g * C) * c, b[2] = (q * y - r * x + s * w) * c, b[3] = (-m * y + n * x - o * w) * c, b[4] = (-h * E + j * B - k * A) * c, b[5] = (d * E - f * B + g * A) * c, b[6] = (-p * y + r * v - s * u) * c, b[7] = (l * y - n * v + o * u) * c, b[8] = (h * D - i * B + k * z) * c, b[9] = (-d * D + e * B - g * z) * c, b[10] = (p * x - q * v + s * t) * c, b[11] = (-l * x + m * v - o * t) * c, b[12] = (-h * C + i * A - j * z) * c, b[13] = (d * C - e * A + f * z) * c, b[14] = (-p * w + q * u - r * t) * c, b[15] = (l * w - m * u + n * t) * c, b) : null
			}, o.toRotationMat = function(a, b) {
				return b || (b = o.create()), b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3], b[4] = a[4], b[5] = a[5], b[6] = a[6], b[7] = a[7], b[8] = a[8], b[9] = a[9], b[10] = a[10], b[11] = a[11], b[12] = 0, b[13] = 0, b[14] = 0, b[15] = 1, b
			}, o.toMat3 = function(a, b) {
				return b || (b = n.create()), b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[4], b[4] = a[5], b[5] = a[6], b[6] = a[8], b[7] = a[9], b[8] = a[10], b
			}, o.toInverseMat3 = function(a, b) {
				var c, d = a[0],
					e = a[1],
					f = a[2],
					g = a[4],
					h = a[5],
					i = a[6],
					j = a[8],
					k = a[9],
					l = a[10],
					m = l * h - i * k,
					o = -l * g + i * j,
					p = k * g - h * j,
					q = d * m + e * o + f * p;
				return q ? (c = 1 / q, b || (b = n.create()), b[0] = m * c, b[1] = (-l * e + f * k) * c, b[2] = (i * e - f * h) * c, b[3] = o * c, b[4] = (l * d - f * j) * c, b[5] = (-i * d + f * g) * c, b[6] = p * c, b[7] = (-k * d + e * j) * c, b[8] = (h * d - e * g) * c, b) : null
			}, o.multiply = function(a, b, c) {
				c || (c = a);
				var d = a[0],
					e = a[1],
					f = a[2],
					g = a[3],
					h = a[4],
					i = a[5],
					j = a[6],
					k = a[7],
					l = a[8],
					m = a[9],
					n = a[10],
					o = a[11],
					p = a[12],
					q = a[13],
					r = a[14],
					s = a[15],
					t = b[0],
					u = b[1],
					v = b[2],
					w = b[3];
				return c[0] = t * d + u * h + v * l + w * p, c[1] = t * e + u * i + v * m + w * q, c[2] = t * f + u * j + v * n + w * r, c[3] = t * g + u * k + v * o + w * s, t = b[4], u = b[5], v = b[6], w = b[7], c[4] = t * d + u * h + v * l + w * p, c[5] = t * e + u * i + v * m + w * q, c[6] = t * f + u * j + v * n + w * r, c[7] = t * g + u * k + v * o + w * s, t = b[8], u = b[9], v = b[10], w = b[11], c[8] = t * d + u * h + v * l + w * p, c[9] = t * e + u * i + v * m + w * q, c[10] = t * f + u * j + v * n + w * r, c[11] = t * g + u * k + v * o + w * s, t = b[12], u = b[13], v = b[14], w = b[15], c[12] = t * d + u * h + v * l + w * p, c[13] = t * e + u * i + v * m + w * q, c[14] = t * f + u * j + v * n + w * r, c[15] = t * g + u * k + v * o + w * s, c
			}, o.multiplyVec3 = function(a, b, c) {
				c || (c = b);
				var d = b[0],
					e = b[1],
					f = b[2];
				return c[0] = a[0] * d + a[4] * e + a[8] * f + a[12], c[1] = a[1] * d + a[5] * e + a[9] * f + a[13], c[2] = a[2] * d + a[6] * e + a[10] * f + a[14], c
			}, o.multiplyVec4 = function(a, b, c) {
				c || (c = b);
				var d = b[0],
					e = b[1],
					f = b[2],
					g = b[3];
				return c[0] = a[0] * d + a[4] * e + a[8] * f + a[12] * g, c[1] = a[1] * d + a[5] * e + a[9] * f + a[13] * g, c[2] = a[2] * d + a[6] * e + a[10] * f + a[14] * g, c[3] = a[3] * d + a[7] * e + a[11] * f + a[15] * g, c
			}, o.translate = function(a, b, c) {
				var d, e, f, g, h, i, j, k, l, m, n, o, p = b[0],
					q = b[1],
					r = b[2];
				return c && a !== c ? (d = a[0], e = a[1], f = a[2], g = a[3], h = a[4], i = a[5], j = a[6], k = a[7], l = a[8], m = a[9], n = a[10], o = a[11], c[0] = d, c[1] = e, c[2] = f, c[3] = g, c[4] = h, c[5] = i, c[6] = j, c[7] = k, c[8] = l, c[9] = m, c[10] = n, c[11] = o, c[12] = d * p + h * q + l * r + a[12], c[13] = e * p + i * q + m * r + a[13], c[14] = f * p + j * q + n * r + a[14], c[15] = g * p + k * q + o * r + a[15], c) : (a[12] = a[0] * p + a[4] * q + a[8] * r + a[12], a[13] = a[1] * p + a[5] * q + a[9] * r + a[13], a[14] = a[2] * p + a[6] * q + a[10] * r + a[14], a[15] = a[3] * p + a[7] * q + a[11] * r + a[15], a)
			}, o.scale = function(a, b, c) {
				var d = b[0],
					e = b[1],
					f = b[2];
				return c && a !== c ? (c[0] = a[0] * d, c[1] = a[1] * d, c[2] = a[2] * d, c[3] = a[3] * d, c[4] = a[4] * e, c[5] = a[5] * e, c[6] = a[6] * e, c[7] = a[7] * e, c[8] = a[8] * f, c[9] = a[9] * f, c[10] = a[10] * f, c[11] = a[11] * f, c[12] = a[12], c[13] = a[13], c[14] = a[14], c[15] = a[15], c) : (a[0] *= d, a[1] *= d, a[2] *= d, a[3] *= d, a[4] *= e, a[5] *= e, a[6] *= e, a[7] *= e, a[8] *= f, a[9] *= f, a[10] *= f, a[11] *= f, a)
			}, o.rotate = function(a, b, c, d) {
				var e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C = c[0],
					D = c[1],
					E = c[2],
					F = Math.sqrt(C * C + D * D + E * E);
				return F ? (1 !== F && (F = 1 / F, C *= F, D *= F, E *= F), e = Math.sin(b), f = Math.cos(b), g = 1 - f, h = a[0], i = a[1], j = a[2], k = a[3], l = a[4], m = a[5], n = a[6], o = a[7], p = a[8], q = a[9], r = a[10], s = a[11], t = C * C * g + f, u = D * C * g + E * e, v = E * C * g - D * e, w = C * D * g - E * e, x = D * D * g + f, y = E * D * g + C * e, z = C * E * g + D * e, A = D * E * g - C * e, B = E * E * g + f, d ? a !== d && (d[12] = a[12], d[13] = a[13], d[14] = a[14], d[15] = a[15]) : d = a, d[0] = h * t + l * u + p * v, d[1] = i * t + m * u + q * v, d[2] = j * t + n * u + r * v, d[3] = k * t + o * u + s * v, d[4] = h * w + l * x + p * y, d[5] = i * w + m * x + q * y, d[6] = j * w + n * x + r * y, d[7] = k * w + o * x + s * y, d[8] = h * z + l * A + p * B, d[9] = i * z + m * A + q * B, d[10] = j * z + n * A + r * B, d[11] = k * z + o * A + s * B, d) : null
			}, o.rotateX = function(a, b, c) {
				var d = Math.sin(b),
					e = Math.cos(b),
					f = a[4],
					g = a[5],
					h = a[6],
					i = a[7],
					j = a[8],
					k = a[9],
					l = a[10],
					m = a[11];
				return c ? a !== c && (c[0] = a[0], c[1] = a[1], c[2] = a[2], c[3] = a[3], c[12] = a[12], c[13] = a[13], c[14] = a[14], c[15] = a[15]) : c = a, c[4] = f * e + j * d, c[5] = g * e + k * d, c[6] = h * e + l * d, c[7] = i * e + m * d, c[8] = f * -d + j * e, c[9] = g * -d + k * e, c[10] = h * -d + l * e, c[11] = i * -d + m * e, c
			}, o.rotateY = function(a, b, c) {
				var d = Math.sin(b),
					e = Math.cos(b),
					f = a[0],
					g = a[1],
					h = a[2],
					i = a[3],
					j = a[8],
					k = a[9],
					l = a[10],
					m = a[11];
				return c ? a !== c && (c[4] = a[4], c[5] = a[5], c[6] = a[6], c[7] = a[7], c[12] = a[12], c[13] = a[13], c[14] = a[14], c[15] = a[15]) : c = a, c[0] = f * e + j * -d, c[1] = g * e + k * -d, c[2] = h * e + l * -d, c[3] = i * e + m * -d, c[8] = f * d + j * e, c[9] = g * d + k * e, c[10] = h * d + l * e, c[11] = i * d + m * e, c
			}, o.rotateZ = function(a, b, c) {
				var d = Math.sin(b),
					e = Math.cos(b),
					f = a[0],
					g = a[1],
					h = a[2],
					i = a[3],
					j = a[4],
					k = a[5],
					l = a[6],
					m = a[7];
				return c ? a !== c && (c[8] = a[8], c[9] = a[9], c[10] = a[10], c[11] = a[11], c[12] = a[12], c[13] = a[13], c[14] = a[14], c[15] = a[15]) : c = a, c[0] = f * e + j * d, c[1] = g * e + k * d, c[2] = h * e + l * d, c[3] = i * e + m * d, c[4] = f * -d + j * e, c[5] = g * -d + k * e, c[6] = h * -d + l * e, c[7] = i * -d + m * e, c
			}, o.frustum = function(a, b, c, d, e, f, g) {
				g || (g = o.create());
				var h = b - a,
					i = d - c,
					j = f - e;
				return g[0] = 2 * e / h, g[1] = 0, g[2] = 0, g[3] = 0, g[4] = 0, g[5] = 2 * e / i, g[6] = 0, g[7] = 0, g[8] = (b + a) / h, g[9] = (d + c) / i, g[10] = -(f + e) / j, g[11] = -1, g[12] = 0, g[13] = 0, g[14] = -(f * e * 2) / j, g[15] = 0, g
			}, o.perspective = function(a, b, c, d, e) {
				var f = c * Math.tan(a * Math.PI / 360),
					g = f * b;
				return o.frustum(-g, g, -f, f, c, d, e)
			}, o.ortho = function(a, b, c, d, e, f, g) {
				g || (g = o.create());
				var h = b - a,
					i = d - c,
					j = f - e;
				return g[0] = 2 / h, g[1] = 0, g[2] = 0, g[3] = 0, g[4] = 0, g[5] = 2 / i, g[6] = 0, g[7] = 0, g[8] = 0, g[9] = 0, g[10] = -2 / j, g[11] = 0, g[12] = -(a + b) / h, g[13] = -(d + c) / i, g[14] = -(f + e) / j, g[15] = 1, g
			}, o.lookAt = function(a, b, c, d) {
				d || (d = o.create());
				var e, f, g, h, i, j, k, l, m, n, p = a[0],
					q = a[1],
					r = a[2],
					s = c[0],
					t = c[1],
					u = c[2],
					v = b[0],
					w = b[1],
					x = b[2];
				return p === v && q === w && r === x ? o.identity(d) : (k = p - v, l = q - w, m = r - x, n = 1 / Math.sqrt(k * k + l * l + m * m), k *= n, l *= n, m *= n, e = t * m - u * l, f = u * k - s * m, g = s * l - t * k, n = Math.sqrt(e * e + f * f + g * g), n ? (n = 1 / n, e *= n, f *= n, g *= n) : (e = 0, f = 0, g = 0), h = l * g - m * f, i = m * e - k * g, j = k * f - l * e, n = Math.sqrt(h * h + i * i + j * j), n ? (n = 1 / n, h *= n, i *= n, j *= n) : (h = 0, i = 0, j = 0), d[0] = e, d[1] = h, d[2] = k, d[3] = 0, d[4] = f, d[5] = i, d[6] = l, d[7] = 0, d[8] = g, d[9] = j, d[10] = m, d[11] = 0, d[12] = -(e * p + f * q + g * r), d[13] = -(h * p + i * q + j * r), d[14] = -(k * p + l * q + m * r), d[15] = 1, d)
			}, o.fromRotationTranslation = function(a, b, c) {
				c || (c = o.create());
				var d = a[0],
					e = a[1],
					f = a[2],
					g = a[3],
					h = d + d,
					i = e + e,
					j = f + f,
					k = d * h,
					l = d * i,
					m = d * j,
					n = e * i,
					p = e * j,
					q = f * j,
					r = g * h,
					s = g * i,
					t = g * j;
				return c[0] = 1 - (n + q), c[1] = l + t, c[2] = m - s, c[3] = 0, c[4] = l - t, c[5] = 1 - (k + q), c[6] = p + r, c[7] = 0, c[8] = m + s, c[9] = p - r, c[10] = 1 - (k + n), c[11] = 0, c[12] = b[0], c[13] = b[1], c[14] = b[2], c[15] = 1, c
			}, o.str = function(a) {
				return "[" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ", " + a[9] + ", " + a[10] + ", " + a[11] + ", " + a[12] + ", " + a[13] + ", " + a[14] + ", " + a[15] + "]"
			};
			var p = {};
			p.create = function(a) {
				var b = new f(4);
				return a ? (b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3]) : b[0] = b[1] = b[2] = b[3] = 0, b
			}, p.createFrom = function(a, b, c, d) {
				var e = new f(4);
				return e[0] = a, e[1] = b, e[2] = c, e[3] = d, e
			}, p.set = function(a, b) {
				return b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3], b
			}, p.equal = function(a, b) {
				return a === b || Math.abs(a[0] - b[0]) < d && Math.abs(a[1] - b[1]) < d && Math.abs(a[2] - b[2]) < d && Math.abs(a[3] - b[3]) < d
			}, p.identity = function(a) {
				return a || (a = p.create()), a[0] = 0, a[1] = 0, a[2] = 0, a[3] = 1, a
			};
			var q = p.identity();
			p.calculateW = function(a, b) {
					var c = a[0],
						d = a[1],
						e = a[2];
					return b && a !== b ? (b[0] = c, b[1] = d, b[2] = e, b[3] = -Math.sqrt(Math.abs(1 - c * c - d * d - e * e)), b) : (a[3] = -Math.sqrt(Math.abs(1 - c * c - d * d - e * e)), a)
				}, p.dot = function(a, b) {
					return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]
				}, p.inverse = function(a, b) {
					var c = a[0],
						d = a[1],
						e = a[2],
						f = a[3],
						g = c * c + d * d + e * e + f * f,
						h = g ? 1 / g : 0;
					return b && a !== b ? (b[0] = -a[0] * h, b[1] = -a[1] * h, b[2] = -a[2] * h, b[3] = a[3] * h, b) : (a[0] *= -h, a[1] *= -h, a[2] *= -h, a[3] *= h, a)
				}, p.conjugate = function(a, b) {
					return b && a !== b ? (b[0] = -a[0], b[1] = -a[1], b[2] = -a[2], b[3] = a[3], b) : (a[0] *= -1, a[1] *= -1, a[2] *= -1, a)
				}, p.length = function(a) {
					var b = a[0],
						c = a[1],
						d = a[2],
						e = a[3];
					return Math.sqrt(b * b + c * c + d * d + e * e)
				}, p.normalize = function(a, b) {
					b || (b = a);
					var c = a[0],
						d = a[1],
						e = a[2],
						f = a[3],
						g = Math.sqrt(c * c + d * d + e * e + f * f);
					return 0 === g ? (b[0] = 0, b[1] = 0, b[2] = 0, b[3] = 0, b) : (g = 1 / g, b[0] = c * g, b[1] = d * g, b[2] = e * g, b[3] = f * g, b)
				}, p.add = function(a, b, c) {
					return c && a !== c ? (c[0] = a[0] + b[0], c[1] = a[1] + b[1], c[2] = a[2] + b[2], c[3] = a[3] + b[3], c) : (a[0] += b[0], a[1] += b[1], a[2] += b[2], a[3] += b[3], a)
				}, p.multiply = function(a, b, c) {
					c || (c = a);
					var d = a[0],
						e = a[1],
						f = a[2],
						g = a[3],
						h = b[0],
						i = b[1],
						j = b[2],
						k = b[3];
					return c[0] = d * k + g * h + e * j - f * i, c[1] = e * k + g * i + f * h - d * j, c[2] = f * k + g * j + d * i - e * h, c[3] = g * k - d * h - e * i - f * j, c
				}, p.multiplyVec3 = function(a, b, c) {
					c || (c = b);
					var d = b[0],
						e = b[1],
						f = b[2],
						g = a[0],
						h = a[1],
						i = a[2],
						j = a[3],
						k = j * d + h * f - i * e,
						l = j * e + i * d - g * f,
						m = j * f + g * e - h * d,
						n = -g * d - h * e - i * f;
					return c[0] = k * j + n * -g + l * -i - m * -h, c[1] = l * j + n * -h + m * -g - k * -i, c[2] = m * j + n * -i + k * -h - l * -g, c
				}, p.scale = function(a, b, c) {
					return c && a !== c ? (c[0] = a[0] * b, c[1] = a[1] * b, c[2] = a[2] * b, c[3] = a[3] * b, c) : (a[0] *= b, a[1] *= b, a[2] *= b, a[3] *= b, a)
				}, p.toMat3 = function(a, b) {
					b || (b = n.create());
					var c = a[0],
						d = a[1],
						e = a[2],
						f = a[3],
						g = c + c,
						h = d + d,
						i = e + e,
						j = c * g,
						k = c * h,
						l = c * i,
						m = d * h,
						o = d * i,
						p = e * i,
						q = f * g,
						r = f * h,
						s = f * i;
					return b[0] = 1 - (m + p), b[1] = k + s, b[2] = l - r, b[3] = k - s, b[4] = 1 - (j + p), b[5] = o + q, b[6] = l + r, b[7] = o - q, b[8] = 1 - (j + m), b
				}, p.toMat4 = function(a, b) {
					b || (b = o.create());
					var c = a[0],
						d = a[1],
						e = a[2],
						f = a[3],
						g = c + c,
						h = d + d,
						i = e + e,
						j = c * g,
						k = c * h,
						l = c * i,
						m = d * h,
						n = d * i,
						p = e * i,
						q = f * g,
						r = f * h,
						s = f * i;
					return b[0] = 1 - (m + p), b[1] = k + s, b[2] = l - r, b[3] = 0, b[4] = k - s, b[5] = 1 - (j + p), b[6] = n + q, b[7] = 0, b[8] = l + r, b[9] = n - q, b[10] = 1 - (j + m), b[11] = 0, b[12] = 0, b[13] = 0, b[14] = 0, b[15] = 1, b
				}, p.slerp = function(a, b, c, d) {
					d || (d = a);
					var e, f, g, h, i = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
					return Math.abs(i) >= 1 ? (d !== a && (d[0] = a[0], d[1] = a[1], d[2] = a[2], d[3] = a[3]), d) : (e = Math.acos(i), f = Math.sqrt(1 - i * i), Math.abs(f) < .001 ? (d[0] = .5 * a[0] + .5 * b[0], d[1] = .5 * a[1] + .5 * b[1], d[2] = .5 * a[2] + .5 * b[2], d[3] = .5 * a[3] + .5 * b[3], d) : (g = Math.sin((1 - c) * e) / f, h = Math.sin(c * e) / f, d[0] = a[0] * g + b[0] * h, d[1] = a[1] * g + b[1] * h, d[2] = a[2] * g + b[2] * h, d[3] = a[3] * g + b[3] * h, d))
				}, p.fromRotationMatrix = function(a, b) {
					b || (b = p.create());
					var c, d = a[0] + a[4] + a[8];
					if (d > 0) c = Math.sqrt(d + 1), b[3] = .5 * c, c = .5 / c, b[0] = (a[7] - a[5]) * c, b[1] = (a[2] - a[6]) * c, b[2] = (a[3] - a[1]) * c;
					else {
						var e = p.fromRotationMatrix.s_iNext = p.fromRotationMatrix.s_iNext || [1, 2, 0],
							f = 0;
						a[4] > a[0] && (f = 1), a[8] > a[3 * f + f] && (f = 2);
						var g = e[f],
							h = e[g];
						c = Math.sqrt(a[3 * f + f] - a[3 * g + g] - a[3 * h + h] + 1), b[f] = .5 * c, c = .5 / c, b[3] = (a[3 * h + g] - a[3 * g + h]) * c, b[g] = (a[3 * g + f] + a[3 * f + g]) * c, b[h] = (a[3 * h + f] + a[3 * f + h]) * c
					}
					return b
				}, n.toQuat4 = p.fromRotationMatrix,
				function() {
					var a = n.create();
					p.fromAxes = function(b, c, d, e) {
						return a[0] = c[0], a[3] = c[1], a[6] = c[2], a[1] = d[0], a[4] = d[1], a[7] = d[2], a[2] = b[0], a[5] = b[1], a[8] = b[2], p.fromRotationMatrix(a, e)
					}
				}(), p.identity = function(a) {
					return a || (a = p.create()), a[0] = 0, a[1] = 0, a[2] = 0, a[3] = 1, a
				}, p.fromAngleAxis = function(a, b, c) {
					c || (c = p.create());
					var d = .5 * a,
						e = Math.sin(d);
					return c[3] = Math.cos(d), c[0] = e * b[0], c[1] = e * b[1], c[2] = e * b[2], c
				}, p.toAngleAxis = function(a, b) {
					b || (b = a);
					var c = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
					if (c > 0) {
						b[3] = 2 * Math.acos(a[3]);
						var d = e.invsqrt(c);
						b[0] = a[0] * d, b[1] = a[1] * d, b[2] = a[2] * d
					} else b[3] = 0, b[0] = 1, b[1] = 0, b[2] = 0;
					return b
				}, p.str = function(a) {
					return "[" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + "]"
				};
			var r = {};
			r.create = function(a) {
				var b = new f(2);
				return a ? (b[0] = a[0], b[1] = a[1]) : (b[0] = 0, b[1] = 0), b
			}, r.createFrom = function(a, b) {
				var c = new f(2);
				return c[0] = a, c[1] = b, c
			}, r.add = function(a, b, c) {
				return c || (c = b), c[0] = a[0] + b[0], c[1] = a[1] + b[1], c
			}, r.subtract = function(a, b, c) {
				return c || (c = b), c[0] = a[0] - b[0], c[1] = a[1] - b[1], c
			}, r.multiply = function(a, b, c) {
				return c || (c = b), c[0] = a[0] * b[0], c[1] = a[1] * b[1], c
			}, r.divide = function(a, b, c) {
				return c || (c = b), c[0] = a[0] / b[0], c[1] = a[1] / b[1], c
			}, r.scale = function(a, b, c) {
				return c || (c = a), c[0] = a[0] * b, c[1] = a[1] * b, c
			}, r.dist = function(a, b) {
				var c = b[0] - a[0],
					d = b[1] - a[1];
				return Math.sqrt(c * c + d * d)
			}, r.set = function(a, b) {
				return b[0] = a[0], b[1] = a[1], b
			}, r.equal = function(a, b) {
				return a === b || Math.abs(a[0] - b[0]) < d && Math.abs(a[1] - b[1]) < d
			}, r.negate = function(a, b) {
				return b || (b = a), b[0] = -a[0], b[1] = -a[1], b
			}, r.normalize = function(a, b) {
				b || (b = a);
				var c = a[0] * a[0] + a[1] * a[1];
				return c > 0 ? (c = Math.sqrt(c), b[0] = a[0] / c, b[1] = a[1] / c) : b[0] = b[1] = 0, b
			}, r.cross = function(a, b, c) {
				var d = a[0] * b[1] - a[1] * b[0];
				return c ? (c[0] = c[1] = 0, c[2] = d, c) : d
			}, r.length = function(a) {
				var b = a[0],
					c = a[1];
				return Math.sqrt(b * b + c * c)
			}, r.squaredLength = function(a) {
				var b = a[0],
					c = a[1];
				return b * b + c * c
			}, r.dot = function(a, b) {
				return a[0] * b[0] + a[1] * b[1]
			}, r.direction = function(a, b, c) {
				c || (c = a);
				var d = a[0] - b[0],
					e = a[1] - b[1],
					f = d * d + e * e;
				return f ? (f = 1 / Math.sqrt(f), c[0] = d * f, c[1] = e * f, c) : (c[0] = 0, c[1] = 0, c[2] = 0, c)
			}, r.lerp = function(a, b, c, d) {
				return d || (d = a), d[0] = a[0] + c * (b[0] - a[0]), d[1] = a[1] + c * (b[1] - a[1]), d
			}, r.str = function(a) {
				return "[" + a[0] + ", " + a[1] + "]"
			};
			var s = {};
			s.create = function(a) {
				var b = new f(4);
				return a ? (b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3]) : b[0] = b[1] = b[2] = b[3] = 0, b
			}, s.createFrom = function(a, b, c, d) {
				var e = new f(4);
				return e[0] = a, e[1] = b, e[2] = c, e[3] = d, e
			}, s.set = function(a, b) {
				return b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3], b
			}, s.equal = function(a, b) {
				return a === b || Math.abs(a[0] - b[0]) < d && Math.abs(a[1] - b[1]) < d && Math.abs(a[2] - b[2]) < d && Math.abs(a[3] - b[3]) < d
			}, s.identity = function(a) {
				return a || (a = s.create()), a[0] = 1, a[1] = 0, a[2] = 0, a[3] = 1, a
			}, s.transpose = function(a, b) {
				if (!b || a === b) {
					var c = a[1];
					return a[1] = a[2], a[2] = c, a
				}
				return b[0] = a[0], b[1] = a[2], b[2] = a[1], b[3] = a[3], b
			}, s.determinant = function(a) {
				return a[0] * a[3] - a[2] * a[1]
			}, s.inverse = function(a, b) {
				b || (b = a);
				var c = a[0],
					d = a[1],
					e = a[2],
					f = a[3],
					g = c * f - e * d;
				return g ? (g = 1 / g, b[0] = f * g, b[1] = -d * g, b[2] = -e * g, b[3] = c * g, b) : null
			}, s.multiply = function(a, b, c) {
				c || (c = a);
				var d = a[0],
					e = a[1],
					f = a[2],
					g = a[3];
				return c[0] = d * b[0] + e * b[2], c[1] = d * b[1] + e * b[3], c[2] = f * b[0] + g * b[2], c[3] = f * b[1] + g * b[3], c
			}, s.rotate = function(a, b, c) {
				c || (c = a);
				var d = a[0],
					e = a[1],
					f = a[2],
					g = a[3],
					h = Math.sin(b),
					i = Math.cos(b);
				return c[0] = d * i + e * h, c[1] = d * -h + e * i, c[2] = f * i + g * h, c[3] = f * -h + g * i, c
			}, s.multiplyVec2 = function(a, b, c) {
				c || (c = b);
				var d = b[0],
					e = b[1];
				return c[0] = d * a[0] + e * a[1], c[1] = d * a[2] + e * a[3], c
			}, s.scale = function(a, b, c) {
				c || (c = a);
				var d = a[0],
					e = a[1],
					f = a[2],
					g = a[3],
					h = b[0],
					i = b[1];
				return c[0] = d * h, c[1] = e * i, c[2] = f * h, c[3] = g * i, c
			}, s.str = function(a) {
				return "[" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + "]"
			};
			var t = {};
			return t.create = function(a) {
				var b = new f(4);
				return a ? (b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3]) : (b[0] = 0, b[1] = 0, b[2] = 0, b[3] = 0), b
			}, t.createFrom = function(a, b, c, d) {
				var e = new f(4);
				return e[0] = a, e[1] = b, e[2] = c, e[3] = d, e
			}, t.add = function(a, b, c) {
				return c || (c = b), c[0] = a[0] + b[0], c[1] = a[1] + b[1], c[2] = a[2] + b[2], c[3] = a[3] + b[3], c
			}, t.subtract = function(a, b, c) {
				return c || (c = b), c[0] = a[0] - b[0], c[1] = a[1] - b[1], c[2] = a[2] - b[2], c[3] = a[3] - b[3], c
			}, t.multiply = function(a, b, c) {
				return c || (c = b), c[0] = a[0] * b[0], c[1] = a[1] * b[1], c[2] = a[2] * b[2], c[3] = a[3] * b[3], c
			}, t.divide = function(a, b, c) {
				return c || (c = b), c[0] = a[0] / b[0], c[1] = a[1] / b[1], c[2] = a[2] / b[2], c[3] = a[3] / b[3], c
			}, t.scale = function(a, b, c) {
				return c || (c = a), c[0] = a[0] * b, c[1] = a[1] * b, c[2] = a[2] * b, c[3] = a[3] * b, c
			}, t.set = function(a, b) {
				return b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3], b
			}, t.equal = function(a, b) {
				return a === b || Math.abs(a[0] - b[0]) < d && Math.abs(a[1] - b[1]) < d && Math.abs(a[2] - b[2]) < d && Math.abs(a[3] - b[3]) < d
			}, t.negate = function(a, b) {
				return b || (b = a), b[0] = -a[0], b[1] = -a[1], b[2] = -a[2], b[3] = -a[3], b
			}, t.length = function(a) {
				var b = a[0],
					c = a[1],
					d = a[2],
					e = a[3];
				return Math.sqrt(b * b + c * c + d * d + e * e)
			}, t.squaredLength = function(a) {
				var b = a[0],
					c = a[1],
					d = a[2],
					e = a[3];
				return b * b + c * c + d * d + e * e
			}, t.lerp = function(a, b, c, d) {
				return d || (d = a), d[0] = a[0] + c * (b[0] - a[0]), d[1] = a[1] + c * (b[1] - a[1]), d[2] = a[2] + c * (b[2] - a[2]), d[3] = a[3] + c * (b[3] - a[3]), d
			}, t.str = function(a) {
				return "[" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + "]"
			}, a && (a.glMatrixArrayType = f, a.MatrixArray = f, a.setMatrixArrayType = b, a.determineMatrixArrayType = c, a.glMath = e, a.vec2 = r, a.vec3 = g, a.vec4 = t, a.mat2 = s, a.mat3 = n, a.mat4 = o, a.quat4 = p), {
				glMatrixArrayType: f,
				MatrixArray: f,
				setMatrixArrayType: b,
				determineMatrixArrayType: c,
				glMath: e,
				vec2: r,
				vec3: g,
				vec4: t,
				mat2: s,
				mat3: n,
				mat4: o,
				quat4: p
			}
		}), define("compute", ["require", "exports", "module"], function(a, b, c) {
			function d(a, b) {
				this.gl = a, this.shader = b.shader, this.mesh = b.mesh, this.uniforms = b.uniforms, this.outputFBO = b.output, this.blend = b.blend, this.nobind = b.nobind, this.nounbind = b.nounbind
			}
			d.prototype.run = function() {
				this.outputFBO && !this.nobind && this.outputFBO.bind();
				var a, b = 0;
				for (var c in this.uniforms) this.uniforms.hasOwnProperty(c) && (a = this.uniforms[c], a.bindTexture && !a.bound && a.bindTexture(b++));
				this.shader.use(), this.shader.uniforms(this.uniforms), "add" === this.blend ? (this.gl.blendFunc(gl.SRC_ALPHA, gl.ONE), this.gl.enable(gl.BLEND)) : this.gl.disable(gl.BLEND), this.mesh.draw(this.shader), this.outputFBO && !this.nounbind && this.outputFBO.unbind();
				for (c in this.uniforms) this.uniforms.hasOwnProperty(c) && (a = this.uniforms[c], a.bindTexture && a.bound && a.unbindTexture())
			}, b.Kernel = d
		}), define("main", ["require", "exports", "module", "game-shim", "engine/fragments", "engine/clock", "engine/input", "engine/utils", "engine/gl/shader", "engine/gl/geometry", "engine/gl/texture", "engine/gl/mesh", "engine/gl/context", "gl-matrix", "compute"], function(a, b, c) {
			function d(a, b, c) {}

			function e() {
				var a = new x(m, 32, 32, m.FLOAT, m.LUMINANCE);
				return a.supported
			}

			function f() {
				l = document.getElementById("fluid_container"), m = z.initialize(l, {
					context: {
						depth: !1
					},
					debug: !1,
					extensions: {
						texture_float: !0
					}
				}, d), o = new s(l), n = new t(l), p = new v(m, resources), window.gl = m, n.mouseUp = function(a, b) {
					h(a, b)
				}, m.getExtension("OES_texture_float_linear"), k = e() ? m.LUMINANCE : m.RGBA, onresize, window.addEventListener("resize", u(q, 250)), "undefined" != typeof FLUID_DEBUG && 1 == FLUID_DEBUG && g(), q()
			}

			function g() {
				j = new Stats, j.setMode(0), j.domElement.style.position = "absolute", j.domElement.style.left = "0px", j.domElement.style.top = "0px", document.body.appendChild(j.domElement)
			}

			function h(a, b) {
				advectVelocityKernel.uniforms.dt = D.step, advectVelocityKernel.run(), C.set([10, 10], addForceKernel.uniforms.force), addForceKernel.run(), velocityBoundaryKernel.run(), divergenceKernel.run();
				for (var c = pressureFBO0, d = pressureFBO1, e = c, f = 0; f < 2 * D.iterations; f++) jacobiKernel.uniforms.pressure = pressureBoundaryKernel.uniforms.pressure = c, jacobiKernel.outputFBO = pressureBoundaryKernel.outputFBO = d, jacobiKernel.run(), pressureBoundaryKernel.run(), e = c, c = d, d = e;
				subtractPressureGradientBoundaryKernel.run()
			}

			function i(a, b, c) {
				l.width = a, l.height = b, m.viewport(0, 0, a, b), m.lineWidth(1);
				var d = 1 / l.width,
					e = 1 / l.height,
					f = C.create([d, e]);
				px1 = C.create([1, l.width / l.height]), inside = new y(m, {
					vertex: w.screen_quad(1 - 2 * d, 1 - 2 * e),
					attributes: {
						position: {}
					}
				}), all = new y(m, {
					vertex: w.screen_quad(1, 1),
					attributes: {
						position: {}
					}
				}), boundary = new y(m, {
					mode: m.LINES,
					vertex: new Float32Array([-1 + 0 * d, -1 + 0 * e, -1 + 0 * d, -1 + 2 * e, 1 - 0 * d, -1 + 0 * e, 1 - 0 * d, -1 + 2 * e, -1 + 0 * d, 1 - 0 * e, -1 + 0 * d, 1 - 2 * e, 1 - 0 * d, 1 - 0 * e, 1 - 0 * d, 1 - 2 * e, -1 + 0 * d, 1 - 0 * e, -1 + 2 * d, 1 - 0 * e, -1 + 0 * d, -1 + 0 * e, -1 + 2 * d, -1 + 0 * e, 1 - 0 * d, 1 - 0 * e, 1 - 2 * d, 1 - 0 * e, 1 - 0 * d, -1 + 0 * e, 1 - 2 * d, -1 + 0 * e]),
					attributes: {
						position: {
							size: 2,
							stride: 16,
							offset: 0
						},
						offset: {
							size: 2,
							stride: 16,
							offset: 8
						}
					}
				}), velocityFBO0 = new x(m, a, b, m.FLOAT), velocityFBO1 = new x(m, a, b, m.FLOAT), divergenceFBO = new x(m, a, b, m.FLOAT, c), pressureFBO0 = new x(m, a, b, m.FLOAT, c), pressureFBO1 = new x(m, a, b, m.FLOAT, c), advectVelocityKernel = new B(m, {
					shader: p.get("kernel", "advect"),
					mesh: inside,
					uniforms: {
						px: f,
						px1: px1,
						scale: 1,
						velocity: velocityFBO0,
						source: velocityFBO0,
						dt: D.step,
						tension: D.tension
					},
					output: velocityFBO1
				}), velocityBoundaryKernel = new B(m, {
					shader: p.get("boundary", "advect"),
					mesh: boundary,
					uniforms: {
						px: f,
						scale: -1,
						velocity: velocityFBO0,
						source: velocityFBO0,
						dt: 1 / 60,
						tension: D.tension
					},
					output: velocityFBO1
				}), cursor = new y(m, {
					vertex: w.screen_quad(d * D.cursor_size * 2, e * D.cursor_size * 2),
					attributes: {
						position: {}
					}
				}), addForceKernel = new B(m, {
					shader: p.get("cursor", "addForce"),
					mesh: cursor,
					blend: "add",
					uniforms: {
						px: f,
						force: C.create([.5, .2]),
						center: C.create([.1, .4]),
						scale: C.create([D.cursor_size * d, D.cursor_size * e])
					},
					output: velocityFBO1
				}), divergenceKernel = new B(m, {
					shader: p.get("kernel", "divergence"),
					mesh: all,
					uniforms: {
						velocity: velocityFBO1,
						px: f,
						divergenceMagnifier: D.divergenceMagnifier
					},
					output: divergenceFBO
				}), jacobiKernel = new B(m, {
					shader: p.get("kernel", "jacobi"),
					mesh: all,
					nounbind: !0,
					uniforms: {
						pressure: pressureFBO0,
						divergence: divergenceFBO,
						alpha: -1,
						beta: .25,
						px: f
					},
					output: pressureFBO1
				}), pressureBoundaryKernel = new B(m, {
					shader: p.get("boundary", "jacobi"),
					mesh: boundary,
					nounbind: !0,
					nobind: !0,
					uniforms: {
						pressure: pressureFBO0,
						divergence: divergenceFBO,
						alpha: -1,
						beta: .25,
						px: f
					},
					output: pressureFBO1
				}), subtractPressureGradientKernel = new B(m, {
					shader: p.get("kernel", "subtractPressureGradient"),
					mesh: all,
					uniforms: {
						scale: 1,
						pressure: pressureFBO0,
						velocity: velocityFBO1,
						px: f
					},
					output: velocityFBO0
				}), subtractPressureGradientBoundaryKernel = new B(m, {
					shader: p.get("boundary", "subtractPressureGradient"),
					mesh: boundary,
					uniforms: {
						scale: -1,
						pressure: pressureFBO0,
						velocity: velocityFBO1,
						px: f
					},
					output: velocityFBO0
				}), drawKernel = new B(m, {
					shader: p.get("kernel", "visualize"),
					mesh: all,
					uniforms: {
						velocity: velocityFBO0,
						brightness: D.brightness,
						cursor_intensity: D.cursor_intensity
					},
					output: null
				});
				var g = n.mouse.x,
					h = n.mouse.y;
				o.ontick = function(a) {
					"undefined" != typeof FLUID_DEBUG && 1 == FLUID_DEBUG && j.begin();
					var b = n.mouse.x * D.resolution,
						c = n.mouse.y * D.resolution,
						f = b - g,
						i = c - h;
					g = b, h = c, 0 === g && 0 === h && (f = i = 0), advectVelocityKernel.uniforms.dt = 1 * D.step, advectVelocityKernel.run(), C.set([f * d * D.cursor_size * D.cursor_force, -i * e * D.cursor_size * D.cursor_force], addForceKernel.uniforms.force), C.set([g * d * 2 - 1, -1 * (h * e * 2 - 1)], addForceKernel.uniforms.center), addForceKernel.run(), velocityBoundaryKernel.run(), divergenceKernel.run();
					for (var k = pressureFBO0, l = pressureFBO1, m = k, o = 0; o < D.iterations; o++) jacobiKernel.uniforms.pressure = pressureBoundaryKernel.uniforms.pressure = k, jacobiKernel.outputFBO = pressureBoundaryKernel.outputFBO = l, jacobiKernel.run(), pressureBoundaryKernel.run(), m = k, k = l, l = m;
					subtractPressureGradientKernel.run(), subtractPressureGradientBoundaryKernel.run(), drawKernel.run(), "undefined" != typeof FLUID_DEBUG && 1 == FLUID_DEBUG && j.end()
				}
			}
			a("game-shim");
			var j, k, l, m, n, o, p, q = function() {
					var a = l.getBoundingClientRect(),
						b = a.width * D.resolution,
						c = a.height * D.resolution;
					c = window.innerHeight * D.resolution, n.updateOffset(), i(b, c, k)
				},
				r = a("engine/fragments"),
				s = a("engine/clock").Clock,
				t = a("engine/input").Handler,
				u = a("engine/utils").debounce,
				v = a("engine/gl/shader").Manager,
				w = a("engine/gl/geometry"),
				x = a("engine/gl/texture").FBO,
				y = a("engine/gl/mesh").Mesh,
				z = a("engine/gl/context"),
				A = a("gl-matrix"),
				B = a("compute").Kernel,
				C = A.vec2,
				D = {
					iterations: 6,
					resolution: .55,
					step: 1 / 180,
					cursor_force: 4,
					cursor_intensity: .6,
					cursor_size: 30,
					brightness: 0,
					divergenceMagnifier: .75,
					tension: .995,
					divColor: [50, 50, 50, .3]
				};
			resources = r.resources, window.gl = m, b.updateSize = q, this.init = f, this.start = function() {
				o.start()
			}, this.stop = function() {
				//o.stop()
			}, this.restart = function() {
				q(), o.start()
			}, window.FluidEffect = this
		}), require(["main"])
}();